onedrive 无管理员账户如何调用 api

in 三言两语 with 17 comments

所有的 onedrive 账户中,无管理员类型的 OneDrive 是最安全的,但是另外一方面,无管理员也不能调用 graph api,使用起来也不太方便。

除了这类原本就没有管理员账户的,还有一种是管理员为了防止滥用,特地关闭 onedrive api 的。无论哪一种,二者都不能使用 graph api,但是,他们都是可以调用 sharepoint api。

基本原理

利用 onedrive 分享可以获得一个免登录的分享链接,点击此链接会获得一个 cookie,利用此 cookie 可以获取 sharepoint 的 api_url 和 access_token。然后就可以调用了 sharepoint 的 api 了。

获取分享链接

2738699289.png

参考此篇 https://www.onesrc.cn/p/onedrive-for-onepoint-configuration.html

eg:https://lovelearn-my.sharepoint.com/:f:/g/personal/admin_share_onesrc_cc/Es6CMetI4fJCr4GqWZ3uvA0BEnzJxxb4CU-iQr04VYomLQ?e=C9K35U

获取 cookie 和 access_token

注:下文出现的 lovelearn-my.sharepoint.comadmin_share_onesrc_cc 需要根据自己的实际情况进行替换。

通过 shareurl 获取 cookie:

GET https://lovelearn-my.sharepoint.com/:f:/g/personal/admin_share_onesrc_cc/Es6CMetI4fJCr4GqWZ3uvA0BEnzJxxb4CU-iQr04VYomLQ?e=C9K35U

响应头中含有 cookie 信息,提取出来即可。

Set-Cookie: FedAuth=xxx; path=/; secure; HttpOnly

再利用 cookie,向特定链接发送 post 请求。

POST https://lovelearn-my.sharepoint.com/personal/admin_share_onesrc_cc/_api/web/GetListUsingPath(DecodedUrl=@a1)/RenderListDataAsStream?@a1='%2Fpersonal%admin_share_onesrc_cc%2FDocuments'&RootFolder=%2Fpersonal%admin_share_onesrc_cc%2FDocuments%2F&TryNewExperienceSingle=TRUE
Accept: application/json;odata=verbose
Content-Type: application/json;odata=verbose
origin: https://lovelearn-my.sharepoint.com
Cookie: FedAuth=xxx; path=/; SameSite=None; secure; HttpOnly

{"parameters":{"__metadata":{"type":"SP.RenderListDataParameters"},"RenderOptions":136967,"AllowMultipleValueFilterForTaxonomyFields":true,"AddRequiredFields":true}}

响应数据为 json,在响应里面ListSchema['.driveAccessToken']ListSchema['.driveUrl'],这两个就是 我们需要的 access_token 和 api_url 。

如何使用

传统的 graph api 接口不变,我们在使用时只需将 api_url 替换为上面获得的 driveUrl 即可,用 driveAccessToken 替代 http header 中的 Authorization 部分即可。
同时,我们的 shareurl 和 cookie 就相当于是 refresh token,可以用它来获得 access_token。

GET ${api_url}/root/children
Accept: application/json, text/plain, */*
Authorization: Bearer ${access_token}

兼容性

office官网文档 有说明 https://graph.microsoft.com/v1.0/ 和 https://{tenant-name}.sharepoint.com/_api/v2.0/sites 是等价的,原有的 graph api 在这里都能使用,所以基本不同担心兼容性啥的。

有一点非常重要的区别是下载链接不再是用@microsoft.graph.downloadUrl 而是换成了 @content.downloadUrl

其他的像新建文件夹、上传文件、删除文件、移动文件等都可以正常使用。

onepoint 已经实现了这些,有兴趣的可以自行体验。

上一篇: 分享一下我获得 npm onepoint 包的过程
下一篇: flash页游seer2折腾日记5-协议的加解密
Responses
  1. smy

    大佬这个方法可以在alist挂载无管理员校园账户的onedrive/sharepoint吗?我现在使用的webdav挂载的,但是它有2G文件大小的限制。

    Reply
    1. _ukuq
      @smy

      没有限制,这个是模拟官方的网页。但估计alist上没人做过这个对接api

      Reply
      1. smy
        @_ukuq

        或者挂载rclone也可以

        Reply
      2. smy
        @_ukuq

        谢谢回复,大佬有思路吗?我自己折腾个试试。

        Reply
  2. 自己登录获取的Auth换Token,到是权限齐全,但是世纪互联不返回Token,难道世纪互联不一样,还是说我搞得不对?

    https://universitytongji-my.sharepoint.cn/personal/xxx_alumni_tongji_edu_cn/_api/web/GetList(@listUrl)/RenderListDataAsStream?@listUrl='/personal/xxx_alumni_tongji_edu_cn/Documents'&TryNewExperienceSingle=TRUE

    不知道博主有没有测试过世纪互联呢?

    Reply
    1. @TaterLi

      世纪互联刚刚试过了, 不行。如果你要是拿来做oneindex之类的,我可以推荐你参考这个 https://github.com/ukuq/onepoint/blob/master/lib/sharepointAPI.js
      这里面是完全在模拟正常的点击操作。不过由于上传api太麻烦,就没有做适配,仅仅实现了文件列表功能,且每次最多列出200文件。

      Reply
      1. @ukuq

        我已经简单挪到了rclone上,还行:https://github.com/nickfox-taterli/rclone

        世纪互联我看了看是V1.0的sharepoint,估计API WRAPPER要重写一个.

        Reply
  3. 搞了很久还是不行,能列文件不能上传,不管怎么设置分享连接,上传都无效.

    如果博主方便的话能做一个LINUX SHELL下的上传程序或者类似的就好了,下面是我测试的创建目录代码没办法完成.提示权限不够,

    # 列文件 headers = { 'Authorization': 'Bearer ' + token } response = requests.get(api_url + 'root/children', headers=headers) print(json.loads(response.text)) # 创建目录 headers = { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' } payload = { "name": 'Test1', "folder": {}, "@microsoft.graph.conflictBehavior": "fail" } response = requests.post(api_url + 'items/' + folder_id + '/children', headers=headers, data=json.dumps(payload)) print(json.loads(response.text))

    Reply
    1. @TaterLi

      要看具体报错才行, 分享的时候有勾选允许任何人编辑吗?

      Reply
      1. @ukuq

        https://pastebin.com/DaE9SJeB

        提示就是{'error': {'code': 'accessDenied', 'message': 'Access denied'}}

        权限是Anyone with the link can edit

        Reply
        1. @TaterLi

          如果你想要用文件管理的api, 可以自己登录账号, 抓那个里面的 cookie 和 access token, 那个权限更强一点, 不过就是要定期更新 cookie 就是了.

          Reply
        2. @TaterLi

          微软限制了分享的链接只能上传和列表权限, 不能新建文件夹 文件删除之类的.

          Reply
          1. @ukuq

            确实只有上传,下载,列文件,和Web上一样.

            Reply
  4. 进行POST后,似乎出现这个问题,搞了好久还是没搞懂,不知道博主能看出是什么毛病吗?

    -1, Microsoft.Data.OData.ODataException The property '__metadata' does not exist on type 'SP.RenderListDataParameters'. Make sure to only use property names that are defined by the type.

    Reply
    1. @TaterLi

      解决了,竟然是UA问题...

      Postman的UA不行,伪造UA解决.

      Reply
  5. 这个很实用啊,但是这个分享链接貌似是有有效期的,过期了应该还要重新获取吧

    Reply
    1. @风也

      可以设置为永不过期

      Reply