php-onedrive 库已停止维护,应改用 microsoft graph sdk 配合 oauth 2.0 授权码流程:注册应用、配置权限、获取凭证、手动实现 state 校验与 code 换 token,并通过 /me/drive/root/children 获取文件列表及 downloadurl 下载。

确认 PHP-OneDrive 库已停止维护,别直接 composer require
PHP-OneDrive(通常指 horizon-line/php-onedrive)早在 2019 年就不再更新,其依赖的微软 Graph API v1.0 认证流程和权限模型已失效。现在执行 composer require horizon-line/php-onedrive 虽能安装,但调用 login() 或 getAccessToken() 会返回 invalid_request 或 unauthorized_client 错误——根本原因是它仍用已弃用的 Azure AD v1.0 endpoint 和隐式授权流。
改用官方推荐:Microsoft Graph SDK + OAuth 2.0 授权码流程
微软当前唯一支持的方式是通过 Microsoft Graph REST API(v1.0 或 beta),配合 msgraph/msgraph-sdk-php 官方 SDK。你需要手动处理 OAuth 2.0 授权码流程,不能跳过。
- 注册应用:在 Azure Portal → App Registrations 创建新应用,设置「重定向 URI」为你的回调地址(如
https://yourdomain.com/callback.php) - 配置权限:在「API permissions」中添加
Files.Read(只读)或Files.ReadWrite(读写),并点击「Grant admin consent」 - 获取凭证:记下
Application (client) ID和Client secrets(不是密码,是生成的密钥值) - 安装 SDK:
composer require microsoft/graph
手写 OAuth 流程时,state 参数和 code 交换必须严格校验
Graph SDK 不封装 OAuth 流程,你得自己实现跳转授权页、接收 code、再用 code 换 access_token。最容易出错的是 state 防 CSRF 校验和 token 请求的 body 格式。
关键点:
- 生成随机
state并存入 session:$_SESSION['oauth_state'] = bin2hex(random_bytes(16)); - 构造授权 URL 时必须带
state和scope=Files.Read(注意 scope 是空格分隔,不是逗号) - 回调页收到
code后,POST 到https://login.microsoftonline.com/common/oauth2/v2.0/token,body 必须是application/x-www-form-urlencoded,包含:client_id、client_secret、code、redirect_uri、grant_type=authorization_code - 响应是 JSON,
access_token字段才是你要传给 Graph SDK 的凭据,不是id_token
用 Graph SDK 读取 OneDrive 文件时,路径和 drive ID 容易混淆
OneDrive for personal(即个人账号)的 Graph endpoint 是 /me/drive,但实际文件操作需明确指定 drive 或 driveItem。新手常把 /me/drive/root/children 返回的 id 当作路径直接拼接,结果 404。
正确做法:
- 列出根目录:
$graph->createRequest('GET', '/me/drive/root/children')->setReturnType(Model\DriveItemCollection::class)->execute(); - 下载文件:用
downloadUrl字段(临时直链),不是拼/me/drive/items/{id}/content—— 后者需要额外 bearer header 且不支持大文件 - 上传小文件(/me/drive/root:/{filename}:/content PUT;大文件走
CreateUploadSession流程 - 注意:个人 OneDrive 的
driveId就是me,不要试图去查/me/drives,那返回的是共享库或团队盘
真正麻烦的不是代码量,而是 Azure AD 应用配置里的每一处勾选、每一条权限声明、每次 token 刷新的 refresh_token 有效期(默认 90 天,需主动轮换),这些细节漏掉一个,整个流程就卡在 401。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











