Office E5 OneDrive API使用指南:注册+密钥获取+获取临时上传链接+分片 您所在的位置:网站首页 onedrive怎么关闭自动保存 Office E5 OneDrive API使用指南:注册+密钥获取+获取临时上传链接+分片

Office E5 OneDrive API使用指南:注册+密钥获取+获取临时上传链接+分片

2023-03-31 21:27| 来源: 网络整理| 查看: 265

异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复;本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告。本人所有文章仅在CSDN、掘金和个人博客(一定是异想之旅域名)发布,除此之外全部是盗文!

本文主要讲解的是自己注册了一个 E5 开发者账号,希望可以将 E5 的 OneDrive 作为网站的文件存储。如果你是希望用户登录自己的 Microsoft 账号后你获取他们自己账号的 OneDrive 文件,那么本文仅作实现参考。

这大概是本人写起来最累的一篇文章,因为我是在研究完这个东西、网站都上线了半年后才开始的。写这篇文章的初衷是真的不希望看到大家被微软晦涩难懂的文档劝退,因此内容可能不全面或出现错误,但保证可用。

事实上,Cloudreve 的添加存储策略页面也在很大程度上帮助了我的研究

在这里插入图片描述

特别说明的是,整个过程虽然理论上可以流畅完成,但如果遇到问题可以尝试给自己的网络施一点魔法。

创建应用

首先打开这个网页,登录自己将用于存储文件的Microsoft账号(应为你的E5中某个启用了OneDrive的账号,而非个人账号):

https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview

如果是世纪互联版本,则链接为 https://portal.azure.cn/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview 世纪互联账号未测试,不保证本文方法可用

登录后打开的页面应该是这样的,如果不是请重新点击上面的链接

在这里插入图片描述

选择左侧的“应用注册”,然后选择“新注册”:

在这里插入图片描述

在新打开的页面中,名称随意,受支持的帐户类型选择第三个 任何组织目录(任何 Azure AD 目录 - 多租户)中的帐户和个人 Microsoft 帐户(例如,Skype、Xbox) ,**重定向URI(可选)**选择 Web,值填写 http://localhost/

在这里插入图片描述

点击“注册”按钮,加载完成后就进入了我们刚刚注册的应用程序主页。我们把应用程序(客户端) ID复制出来保存好。

在这里插入图片描述

点击“证书和密码”,再选择“新客户端密码”,截止期限根据自己需求选择(目前微软不提供永久有效的选项了,为防止频繁更新建议直接选到最长24个月),说明随意

在这里插入图片描述

然后我们就可以看到创建好的值和机密ID啦,请务必保存好,关闭页面后就无法再看到“值”了。

在这里插入图片描述

至此,我们的应用注册过程完成,现在手中获得了该应用程序的客户端ID以及客户端密码(刚刚那一步看到的“值”)

获取鉴权 Token

官方文档:https://learn.microsoft.com/zh-cn/onedrive/developer/rest-api/getting-started/graph-oauth?view=odsp-graph-online

官方已经说明了,这一个步骤有令牌流和代码流两种方式。前者虽然流程上更简单,但是获取到的 access_token 有效期仅8小时,到期后需要重新手动登录 Microsoft 账户才能继续调用 API(不考虑你想用爬虫操作Microsoft Login),这显然不适合我们的脚本。

构造并在浏览器中访问这个链接:

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!如果不一样,我不保证你后面的步骤顺利。

于是我构造出来的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/

在浏览器中访问之后,打开的是一个经典的 Microsoft 账号登录界面,正常登录我们要用来存储文件的账号即可

在这里插入图片描述

授权后会跳转到 localhost,此时这个网页应该会因为不存在打不开,不过没关系,我们只需要把地址栏中的内容复制出来,结构应该长这样:

http://localhost/ ?code=xxxxx &session_state=xxxxx#

此处我们记录 code 值,并构造这样的一个访问:

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)

其中需要替换的三个值我们在前面都已经得到了,不再赘述。

如果一群正常,你将会得到一个格式类似于下面这样的 JSON:

{ "token_type":"bearer", "expires_in": 5126, "ext_expires_in": 5126, "scope":"wl.basic onedrive.readwrite", "access_token":"EwCo...AA==", "refresh_token":"eyJh...9323" }

也可能略有不同,没关系,最重要的 access_token 和 refresh_token 有就行。

到这一步,我们就可以拿着 access_token 愉快地去调 API 了。但是如你所见,这个令牌是有有效期的,如果过期了之后,需要我们拿着 refresh_token 去兑换新的令牌

所以 refresh_token 是需要程序保存起来以便未来使用的,并且为了程序效率同时防止不必要的麻烦,建议把获取到每个 access_token 的时间也保存,并在每次发送请求前通过时间信息检测一下该令牌是否过期,不要等到 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 的请求都应由服务端发出以保证安全。

OneDrive 提供两种上传模式,第一种是直接使用 access_token 鉴权并上传,这种方式不适合给用户使用且最大仅支持4MB文件,所以不再赘述,有需要可以自己去看。

此处我们介绍第二种,即先使用 access_token 获取一个上传会话,然后客户端拿到这个上传会话后可以直接免鉴权上传。

构造如下的请求:

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 两个参数,后者老生常谈了,前者就是我们文件在 OneDrive 上的存储路径,注意一下最前面需要有一个斜杠,后面不用,例如 /test.txt

更多可以在 body 中指定的参数详见官方文档,此处我们指定的 "@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 值 。

为了防止大家眼大露神,把文档中很重要的一句话贴过来:

注意:如果应用将一个文件拆分为多个字节范围,则每个字节范围的大小必须是 320 KiB(327,680 个字节)的倍数。 如果使用的片断大小不能被 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; // 当前分片的起始字节 let end = Math.min(piece, size); // 当前分片的结束字节 let cnt = Math.ceil(size / piece); // 分片数 while (start 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": "[email protected]", "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 来下载。

构造请求:

GET https://graph.microsoft.com/v1.0/me/drive/items/root:{path}:', Authorization: Bearer {access_token}

此处的 path 和上面创建上传会话的时候使用的应一致(前面都要有斜杠),access_token 不必再说了。

这个请求返回的是一个巨长的 JSON,把这个文件几乎所有的信息全给你了,但是我们只需要获取到 @microsoft.graph.downloadUrl 这一项即可。其值是一个 URL,访问这个 URL 可以免鉴权下载文件,但是有效期只有一小时。

参考链接:

获取文件或文件夹 - OneDrive API - OneDrive dev center | Microsoft LearnDriveItem - OneDrive API - OneDrive dev center | Microsoft Learn(这个是有关返回的 JSON 各项值的说明)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有