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

异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复;本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告。本人所有文章仅在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_tokenrefresh_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_tokenrefresh_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"
    }
}

此处需要替换 pathaccess_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 < 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 来下载。

构造请求:

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 Learn
  • DriveItem - OneDrive API - OneDrive dev center | Microsoft Learn(这个是有关返回的 JSON 各项值的说明)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/4388.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 各种锁的理解与实现

1. volatile 是轻量级锁&#xff1a; 只能修饰在变量上&#xff0c;使得 cpu 每次对于该变量的修改和读取都从内存中操作&#xff0c;而不是从CPU cache 中操作&#xff0c;保证共享变量对所有线程的可见性&#xff0c;但是并不能保证原子性 2. synchronized 悲观锁&#xff…

Mybatis的CRUD使用详解

文章目录一.Mybatis的CRUD使用详解1.1 select1.2 insert1.3 update1.3 delete二.常见错误一.Mybatis的CRUD使用详解 注意&#xff1a;增删改需要提交事务。 namespace&#xff08;UserMapper.xml&#xff09; namespace中的包名需要和Dao/mapper接口的包名一致。 <!--na…

论文阅读 10 | Instance Credibility Inference for Few-Shot Learning

小样本学习的实例可信度推理作者摘要1. Introduction2. Related Work作者 摘要 小样本学习&#xff08;FSL&#xff09;旨在识别每个类别极其有限的训练数据的新对象。以前的努力是通过利用元学习范式或数据增强中的新原理来缓解这个极其缺乏数据的问题。相比之下&#xff0c;本…

taro--之使用nutui组件库

安装 Taro 脚手架# 使用 npm 安装 CLI npm install -g tarojs/cli# 使用 yarn 安装 CLI yarn global add tarojs/cli# 使用 cnpm 安装 CLI cnpm install -g tarojs/cli使用 NutUI 模板创建项目1、使用命令创建 Taro 项目&#xff1a;taro init myApp2、按照下方图片依次选择&am…

ChatGPT如何批量撰写最新的热点自媒体文章

如何用ChatGPT创作高质量的自媒体文章 自媒体已成为互联网上的一个重要组成部分&#xff0c;无论您是想在社交媒体、博客中发布内容&#xff0c;高质量的文章都是自媒体成功的重要组成部分。ChatGPT是一个智能文章生成器&#xff0c;能够帮助创作者快速、高效地生成高质量的自…

数据结构——二叉搜索树

一、二叉搜索树概念 二叉搜索树又叫二叉排序树&#xff0c;它或是空树&#xff0c;或是具有以下性质的二叉树&#xff1a; &#xff08;1&#xff09;若它的左子树不为空&#xff0c;则左子树上的所有节点的值都小于根节点的值&#xff1b; &#xff08;2&#xff09;若它的…

LeetCode-718. 最长重复子数组

目录题目思路动态规划遇到的坑动态规划(优化)题目来源 718. 最长重复子数组 题目思路 用二维数组可以记录两个字符串的所有比较情况&#xff0c;这样就比较好推递推公式了。 动态规划 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j]的定义也就决定…

【云原生】我将ChatGPT变成Kubernetes 和Helm 终端

{kubectl get po&#xff0c;deploy&#xff0c;svc}{kubectl run --imagenginx nginx-app --port80 --env“DOMAINcluster”}{kubectl expose deployment nginx-app --port80 --namenginx-http}{kubectl get po&#xff0c;svc&#xff0c;deploy}{curl 10.100.67.94:80}{helm…

Spring事务

目录 手动操作 声明式提交 注解的属性 事务隔离级别 事务传播机制 事务可以将一组操作封装成为一个单元&#xff0c;一组操作要么全部成功&#xff0c;要么全部失败 Mysql中操作事务&#xff0c;有三个步骤&#xff1b; 1、start transaction &#xff1b;开启事务 2、com…

springboot 整合Mybatis-Plus分页、自动填充功能

springboot 整合Mybatis-Plus分页、自动填充功能功能 此次分页、自动填充功能的实现是在Spring Boot整合 druid、Mybatis-plus实现的基础上完成的&#xff0c;包括数据源配置、各种依赖添加、mapper和service的实现。不在重复记录。 Java开发手册要求数据表必须要有三个字段&am…

【lwIP(第九章)】ICMP协议

目录一、ICMP协议简介1. ICMP协议类型与结构2. ICMP 差错报文3. ICMP 查询报文二、ICMP协议原理1. ICMP报文数据结构2. ICMP的差错报文3. 差错报文的原理4. ICMP的查询报文一、ICMP协议简介 ICMP协议是一个网络层协议。 一个新搭建好的网络&#xff0c;往往需要先进行一个简单的…

为什么说学人工智能一定要学Python?

学习人工智能需要掌握大量的数据处理和算法实现&#xff0c;而Python作为一种高级编程语言&#xff0c;具有简单易学、灵活多变、开源丰富的库等优点&#xff0c;成为了人工智能领域广泛应用的语言之一。 具体来说&#xff0c;Python在人工智能中的优势包括&#xff1a; ​​…

Matlab群体智能优化算法之巨型睡莲优化算法(VAO)

Matlab群体智能优化算法之巨型睡莲优化算法(VAO) 摘要&#xff1a;介绍一种新型智能优化算法&#xff0c;巨型睡莲优化算法。其应用于24个基准测试函数&#xff0c;并与其他10个著名算法进行了比较。提出的算法在10个优化问题上进行了测试&#xff1a;最小生成树、枢纽位置分配…

Nginx学习(9)—— 负载均衡模块

文章目录Nginx负载均衡模块负载均衡配置指令钩子初始化配置初始化请求peer.get和peer.free回调函数小结Nginx负载均衡模块 负载均衡模块用于从”upstream”指令定义的后端主机列表中选取一台主机。nginx先使用负载均衡模块找到一台主机&#xff0c;再使用upstream模块实现与这…

HTTP代理端口是什么意思?

HTTP代理端口是指代理服务器所使用的端口。代理服务器是一种介于客户端和服务器之间的计算机系统&#xff0c;它可以拦截客户端发送给服务器的请求&#xff0c;并将其转发到服务器。而HTTP代理端口则是代理服务器上专门用于处理HTTP请求和响应的端口号。默认情况下&#xff0c;…

【Java】JavaSE概要

整理&#xff1a;【狂神说Java】JavaSE阶段回顾总结_哔哩哔哩_bilibili JavaSE概要 简介 JDK&#xff1a;开发者工具包 JRE&#xff1a;运行环境 //Hello.java public class Hello{public static void main(String[] args){System.out.println("Hello,World!");} }…

Redis数据库

一、关系数据库与非关系型数据库概述 1、关系型数据库 关系型数据库是一个结构化的数据库&#xff0c;创建在关系模型&#xff08;二维表格模型&#xff09;基础上&#xff0c;一般面向于记录。 SQL 语句&#xff08;标准数据查询语言&#xff09;就是一种基于关系型数据库的语…

Spring Boot基础学习之(六):前后端交互实现用户登录界面

本篇博客写的内容&#xff0c;是一个系列&#xff0c;内容都是关于spring boot架构的学习&#xff0c;实现前后端交互&#xff0c;极大的解放双手spring boot学习系列这是关于spring boot的专栏&#xff0c;后期也会不定期进行更新。内容都是有序号的&#xff0c;一步接着一步。…

有人物联口红DTU DR154配置与RS 485传感器数据处理

一、硬件设备 &#xff08;1&#xff09;有人物联口红DTU DR154&#xff08;RS 485版本&#xff09; 这个DTU非常给力&#xff0c;不用插卡自带esim卡&#xff0c;送8年流量&#xff0c;配置的话通过小程序【联博士】蓝牙配置&#xff08;手机扫描DTU背后的二维码即可&#x…

界面开发框架Qt新手入门教程 - 项目视图示例介绍

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。Qt提供了许多功能&…