異想之旅:本人原創(chuàng)博客完全手敲,絕對非搬運,全網(wǎng)不可能有重復;本人無團隊,僅為技術(shù)愛好者進行分享,所有內(nèi)容不牽扯廣告。本人所有文章僅在CSDN、掘金和個人博客(一定是異想之旅域名)發(fā)布,除此之外全部是盜文!
本文主要講解的是自己注冊了一個 E5 開發(fā)者賬號,希望可以將 E5 的 OneDrive 作為網(wǎng)站的文件存儲。如果你是希望用戶登錄自己的 Microsoft 賬號后你獲取他們自己賬號的 OneDrive 文件,那么本文僅作實現(xiàn)參考。
這大概是本人寫起來最累的一篇文章,因為我是在研究完這個東西、網(wǎng)站都上線了半年后才開始的。寫這篇文章的初衷是真的不希望看到大家被微軟晦澀難懂的文檔勸退,因此內(nèi)容可能不全面或出現(xiàn)錯誤,但保證可用。
事實上,Cloudreve 的添加存儲策略頁面也在很大程度上幫助了我的研究
特別說明的是,整個過程雖然理論上可以流暢完成,但如果遇到問題可以嘗試給自己的網(wǎng)絡施一點魔法。
創(chuàng)建應用
首先打開這個網(wǎng)頁,登錄自己將用于存儲文件的Microsoft賬號(應為你的E5中某個啟用了OneDrive的賬號,而非個人賬號):
https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview
如果是世紀互聯(lián)版本,則鏈接為
https://portal.azure.cn/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview
世紀互聯(lián)賬號未測試,不保證本文方法可用
登錄后打開的頁面應該是這樣的,如果不是請重新點擊上面的鏈接
選擇左側(cè)的“應用注冊”,然后選擇“新注冊”:
在新打開的頁面中,名稱隨意,受支持的帳戶類型選擇第三個 任何組織目錄(任何 Azure AD 目錄 - 多租戶)中的帳戶和個人 Microsoft 帳戶(例如,Skype、Xbox)
,**重定向URI(可選)**選擇 Web
,值填寫 http://localhost/
點擊“注冊”按鈕,加載完成后就進入了我們剛剛注冊的應用程序主頁。我們把應用程序(客戶端) ID復制出來保存好。
點擊“證書和密碼”,再選擇“新客戶端密碼”,截止期限根據(jù)自己需求選擇(目前微軟不提供永久有效的選項了,為防止頻繁更新建議直接選到最長24個月),說明隨意
然后我們就可以看到創(chuàng)建好的值和機密ID啦,請務必保存好,關(guān)閉頁面后就無法再看到“值”了。
至此,我們的應用注冊過程完成,現(xiàn)在手中獲得了該應用程序的客戶端ID以及客戶端密碼(剛剛那一步看到的“值”)
獲取鑒權(quán) Token
官方文檔:https://learn.microsoft.com/zh-cn/onedrive/developer/rest-api/getting-started/graph-oauth?view=odsp-graph-online
官方已經(jīng)說明了,這一個步驟有令牌流和代碼流兩種方式。前者雖然流程上更簡單,但是獲取到的 access_token 有效期僅8小時,到期后需要重新手動登錄 Microsoft 賬戶才能繼續(xù)調(diào)用 API(不考慮你想用爬蟲操作Microsoft Login),這顯然不適合我們的腳本。
構(gòu)造并在瀏覽器中訪問這個鏈接:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
client_id={client_id}
&scope={scope}
&response_type=code
&redirect_uri=http://localhost/
其中,client_id
就是我們上一步獲取的客戶端ID,scope
指作用域,OneDrive官方的詳細介紹在這里
建議和我一樣填寫 files.readwrite.all offline_access
!如果不一樣,我不保證你后面的步驟順利。
于是我構(gòu)造出來的URI便是(client_id
中省略了最后一部分)
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=2dde8638-6489-4fc2-bfec-xxxxxxxxxxxx&scope=files.readwrite.all%20offline_access&response_type=code&redirect_uri=http://localhost/
在瀏覽器中訪問之后,打開的是一個經(jīng)典的 Microsoft 賬號登錄界面,正常登錄我們要用來存儲文件的賬號即可
授權(quán)后會跳轉(zhuǎn)到 localhost,此時這個網(wǎng)頁應該會因為不存在打不開,不過沒關(guān)系,我們只需要把地址欄中的內(nèi)容復制出來,結(jié)構(gòu)應該長這樣:
http://localhost/
?code=xxxxx
&session_state=xxxxx#
此處我們記錄 code
值,并構(gòu)造這樣的一個訪問:
POST https://login.microsoftonline.com/common/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={client_id}&redirect_uri=http://localhost/&client_secret={client_secret}
&code={code}&grant_type=authorization_code
對應的 Python 代碼:
from requests import *
r = post('https://login.microsoftonline.com/common/oauth2/v2.0/token',
data={
'client_id': '{client_id}',
'redirect_uri': 'http://localhost/',
'client_secret': '{client_secret}',
'code': '{code}',
'grant_type': 'authorization_code'
})
print(r.text)
其中需要替換的三個值我們在前面都已經(jīng)得到了,不再贅述。
如果一群正常,你將會得到一個格式類似于下面這樣的 JSON:
{
"token_type":"bearer",
"expires_in": 5126,
"ext_expires_in": 5126,
"scope":"wl.basic onedrive.readwrite",
"access_token":"EwCo...AA==",
"refresh_token":"eyJh...9323"
}
也可能略有不同,沒關(guān)系,最重要的 access_token
和 refresh_token
有就行。
到這一步,我們就可以拿著 access_token
愉快地去調(diào) API 了。但是如你所見,這個令牌是有有效期的,如果過期了之后,需要我們拿著 refresh_token
去兌換新的令牌
所以 refresh_token
是需要程序保存起來以便未來使用的,并且為了程序效率同時防止不必要的麻煩,建議把獲取到每個 access_token
的時間也保存,并在每次發(fā)送請求前通過時間信息檢測一下該令牌是否過期,不要等到 API 報錯再去重新申請令牌
兌換新的 access_token
的請求格式如下
POST https://login.microsoftonline.com/common/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={client_id}&redirect_uri=http://localhost/&client_secret={client_secret}
&refresh_token={refresh_token}&grant_type=refresh_token
其響應格式還是一個和上面類似的 JSON,包含新的 access_token
和 refresh_token
上傳文件
從此處開始,正常情況下,需要 access_token
的請求都應由服務端發(fā)出以保證安全。
OneDrive 提供兩種上傳模式,第一種是直接使用 access_token
鑒權(quán)并上傳,這種方式不適合給用戶使用且最大僅支持4MB文件,所以不再贅述,有需要可以自己去看。
此處我們介紹第二種,即先使用 access_token
獲取一個上傳會話,然后客戶端拿到這個上傳會話后可以直接免鑒權(quán)上傳。
構(gòu)造如下的請求:
POST https://graph.microsoft.com/v1.0/me/drive/root:{path}:/createUploadSession
Authorization: Bearer {access_token}
Content-Type: application/json
{
"item": {
"@microsoft.graph.conflictBehavior": "rename"
}
}
此處需要替換 path
和 access_token
兩個參數(shù),后者老生常談了,前者就是我們文件在 OneDrive 上的存儲路徑,注意一下最前面需要有一個斜杠,后面不用,例如 /test.txt
更多可以在 body 中指定的參數(shù)詳見官方文檔,此處我們指定的
"@microsoft.graph.conflictBehavior": "rename"
是指如果存在同名文件則為新上傳的文件重命名。
示例 Python:
path = '/test.txt'
access_token = 'xxxxxx'
r = post(
f'https://graph.microsoft.com/v1.0/me/drive/root:{path}:/createUploadSession',
headers={
'Authorization': 'Bearer ' + access_token,
'Content-Type': 'application/json'
},
data=json.dumps({
'item': {
'@microsoft.graph.conflictBehavior': 'rename',
},
}),
)
print(r.json())
正常情況下你會收到這樣的返回:
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#microsoft.graph.uploadSession",
"expirationDateTime": "2023-03-25T07:41:03.482Z",
"nextExpectedRanges": [
"0-"
],
"uploadUrl": "https://yxzl-my.sharepoint.com/..."
}
接下來的東西應該看官方文檔就能懂了,大家自行閱讀一下。剛剛在JSON中獲取到的 uploadUrl
就是文檔中所說的 在 createUploadSession 響應中收到的 uploadUrl 值
。
為了防止大家眼大露神,把文檔中很重要的一句話貼過來:
注意:如果應用將一個文件拆分為多個字節(jié)范圍,則每個字節(jié)范圍的大小必須是 320 KiB(327,680 個字節(jié))的倍數(shù)。 如果使用的片斷大小不能被 320 KiB 整除,會導致在提交某些文件時出錯。
此處給出 Python 客戶端上傳文件的代碼示例:
from requests import *
file = open('D:/Desktop/1.txt', 'rb').read()
length = len(file)
r = put(
'https://yxzl-my.sharepoint.com/...',
data=file,
headers={
'Content-Length': f'{length}',
'Content-Range': f'bytes 0-{length - 1}/{length}'
})
print(r)
print(r.text)
JavaScript Axios 的上傳示例:
import { Axios } from "axios";
const uploadFile = async (file, uploadUrl) => {
/*
file: 要上傳的文件對象
uploadUrl: 獲取的上傳會話
*/
const size = file.size; // 文件大小
const piece = 1024 * 1024 * 10; // 分片大小
let start = 0; // 當前分片的起始字節(jié)
let end = Math.min(piece, size); // 當前分片的結(jié)束字節(jié)
let cnt = Math.ceil(size / piece); // 分片數(shù)
while (start < size - 1) {
await Axios.put(uploadUrl, this.uploadFile.slice(start, end), {
headers: {
"Content-Range": `bytes ${start}-${end - 1}/${size}`,
},
});
cnt--;
if (cnt === 0) {
alert("上傳成功");
return;
}
start = end;
end = Math.min(start + piece, size);
}
};
上傳成功的返回如下(如果分片則是最后一個分片的返回),不過一點用也沒有
{
"@odata.context": "https://yxzl-my.sharepoint.com/.../$metadata#items/$entity",
"@content.downloadUrl": "https://yxzl-my.sharepoint.com/.../download.aspx?UniqueId=...",
"createdBy": {
"application": {
"id": "...",
"displayName": "OneDriveTest"
},
"user": {
"email": "yixiangzhilv@yxzl.onmicrosoft.com",
"id": "...",
"displayName": "王 子涵"
}
},
"createdDateTime": "2023-03-25T07:26:03Z",
"eTag": "\"{F51D59DC-4D2F-466F-9CF0-E9895FF154C2},3\"",
"id": "...",
"lastModifiedBy": {
"application": ...,
"user": ...
},
"lastModifiedDateTime": "2023-03-25T07:39:52Z",
"name": "a.txt",
"parentReference": {
"driveType": "business",
"driveId": "b!...",
"id": "...",
"path": "/drive/root:"
},
"webUrl": "https://yxzl-my.sharepoint.com/.../a.txt",
"cTag": "\"c:{F51D59DC-4D2F-466F-9CF0-E9895FF154C2},2\"",
"file": {
"hashes": {
"quickXorHash": "..."
},
"irmEffectivelyEnabled": false,
"irmEnabled": false,
"mimeType": "text/plain"
},
"fileSystemInfo": {
"createdDateTime": "2023-03-25T07:26:03Z",
"lastModifiedDateTime": "2023-03-25T07:39:52Z"
},
"size": 150
}
你要說他有用的話,可能那個 donwloadUrl
稍微有點,但是那玩意有效期也不長
獲取文件下載鏈接
這個就很簡單了,此處介紹的方法是先獲取一個文件的詳細信息,再通過返回的 @microsoft.graph.downloadUrl
來下載。
構(gòu)造請求:
GET https://graph.microsoft.com/v1.0/me/drive/items/root:{path}:',
Authorization: Bearer {access_token}
此處的 path
和上面創(chuàng)建上傳會話的時候使用的應一致(前面都要有斜杠),access_token
不必再說了。
這個請求返回的是一個巨長的 JSON,把這個文件幾乎所有的信息全給你了,但是我們只需要獲取到 @microsoft.graph.downloadUrl
這一項即可。其值是一個 URL,訪問這個 URL 可以免鑒權(quán)下載文件,但是有效期只有一小時。文章來源:http://www.zghlxwxcb.cn/news/detail-439679.html
參考鏈接:文章來源地址http://www.zghlxwxcb.cn/news/detail-439679.html
- 獲取文件或文件夾 - OneDrive API - OneDrive dev center | Microsoft Learn
- DriveItem - OneDrive API - OneDrive dev center | Microsoft Learn(這個是有關(guān)返回的 JSON 各項值的說明)
到了這里,關(guān)于Office E5 OneDrive API使用指南:注冊+密鑰獲取+獲取臨時上傳鏈接+分片的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!