You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React调用Microsoft Graph API获取OneDrive文件时遇401未授权错误

问题:调用Microsoft Graph API的/me/drive/root/children接口返回401未授权

我正在开发一个React应用,使用Microsoft Graph API从OneDrive获取文件。调用/me接口能成功获取账户信息:

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
    "businessPhones": [],
    "displayName": [NAME],
    "givenName": null,
    "jobTitle": null,
    "mail": [EMAIL],
    "mobilePhone": null,
    "officeLocation": null,
    "preferredLanguage": null,
    "surname": null,
    "userPrincipalName": [USER_PRINCIPAL_NAME],
    "id": [ID]
}

但调用/me/drive/root/children接口时出现401未授权错误:

HTTPMessageHandler.ts:29 
        
       GET https://graph.microsoft.com/v1.0/me/drive/root/children 401 (Unauthorized)
(anonymous) @ HTTPMessageHandler.ts:29
(anonymous) @ tslib.es6.mjs:121
__awaiter @ tslib.es6.mjs:117
execute @ HTTPMessageHandler.ts:28
(anonymous) @ TelemetryHandler.ts:91
(anonymous) @ tslib.es6.mjs:121
__awaiter @ tslib.es6.mjs:117
execute @ TelemetryHandler.ts:66
(anonymous) @ RetryHandler.ts:173
(anonymous) @ tslib.es6.mjs:121
__awaiter @ tslib.es6.mjs:117
executeWithRetry @ RetryHandler.ts:172
(anonymous) @ RetryHandler.ts:196
(anonymous) @ tslib.es6.mjs:121
__awaiter @ tslib.es6.mjs:117
execute @ RetryHandler.ts:192
(anonymous) @ AuthenticationHandler.ts:88
fulfilled @ tslib.es6.mjs:118
Promise.then (async)
step @ tslib.es6.mjs:120
(anonymous) @ tslib.es6.mjs:121
__awaiter @ tslib.es6.mjs:117
execute @ AuthenticationHandler.ts:63
(anonymous) @ HTTPClient.ts:88
(anonymous) @ tslib.es6.mjs:121
__awaiter @ tslib.es6.mjs:117
sendRequest @ HTTPClient.ts:81
(anonymous) @ GraphRequest.ts:372
(anonymous) @ tslib.es6.mjs:121
__awaiter @ tslib.es6.mjs:117
send @ GraphRequest.ts:366
(anonymous) @ GraphRequest.ts:635
(anonymous) @ tslib.es6.mjs:121
__awaiter @ tslib.es6.mjs:117
get @ GraphRequest.ts:630
getData @ initializeAuthProcess.js:26
initializeAuthProcess @ initializeAuthProcess.js:12
await in initializeAuthProcess (async)
(anonymous) @ App.js:31
commitHookEffectListMount @ react-dom.development.js:23150
commitPassiveMountOnFiber @ react-dom.development.js:24926
commitPassiveMountEffects_complete @ react-dom.development.js:24891
commitPassiveMountEffects_begin @ react-dom.development.js:24878
commitPassiveMountEffects @ react-dom.development.js:24866
flushPassiveEffectsImpl @ react-dom.development.js:27039
flushPassiveEffects @ react-dom.development.js:26984
(anonymous) @ react-dom.development.js:26769
workLoop @ scheduler.development.js:266
flushWork @ scheduler.development.js:239
performWorkUntilDeadline @ scheduler.development.js:533
initializeAuthProcess.js:29 getData error Error: There has been an error authenticating the request.
    at GraphErrorHandler.constructErrorFromResponse (GraphErrorHandler.ts:77:1)
    at GraphErrorHandler.<anonymous> (GraphErrorHandler.ts:104:1)
    at Generator.next (<anonymous>)
    at tslib.es6.mjs:121:1
    at new Promise (<anonymous>)
    at __awaiter (tslib.es6.mjs:117:1)
    at GraphErrorHandler.getError (GraphErrorHandler.ts:101:1)
    at GraphRequest.<anonymous> (GraphRequest.ts:391:1)
    at Generator.throw (<anonymous>)
    at rejected (tslib.es6.mjs:119:1)

我已在登录作用域中包含Files.ReadWrite.All等相关权限,初始化代码如下:

import { Client } from '@microsoft/microsoft-graph-client';

export const initializeAuthProcess = async (instance) => {
    try {
      await instance.initialize();
      const authResponse = await instance.loginPopup({
        redirectUri: 'http://localhost:3000',
        scopes: ["User.Read", "User.Read.All", "User.ReadBasic.All", "User.ReadWrite", "User.ReadWrite.All", "Files.Read", "Files.Read.All", "Files.Read.Selected", "Files.ReadWrite", "Files.ReadWrite.All", "Files.ReadWrite.AppFolder", "Files.ReadWrite.Selected"],
        prompt: "select_account"
      });
      const accessToken = authResponse.accessToken;
      getData(accessToken)
    } catch (e) {
      console.error("initializeAuthProcess error", e);
    }
};

async function getData(accessToken) {
    const client = Client.init({
      authProvider: (done) => {
        done(null, accessToken);
      },
    });
  
    try {
      const data = await client.api('/me/drive/root/children').get();
      console.log("data", data);
    } catch (error) {
      console.error("getData error", error);
    }
}

App.js代码:

import {
  PublicClientApplication
} from "@azure/msal-browser";
import { MsalProvider, useMsal } from "@azure/msal-react";
import { useEffect } from "react";
import { initializeAuthProcess } from "./functions/initializeAuthProcess";

const msalConfig = {
  auth: {
    clientId: [clientId],
    authority: [authority],
    redirectUri: 'http://localhost:3000'
  }
};

const pca = new PublicClientApplication(msalConfig);

function App() {
  return (
    <MsalProvider instance={pca}>
      <OneDriveFiles />
    </MsalProvider>
  );
}

function OneDriveFiles() {
  const { accounts, instance } = useMsal();

  useEffect(() => {
    if(instance){
      initializeAuthProcess(instance);
    }

  }, [accounts, instance]);

  return null;
}

export default App;

我已在Azure Active Directory中为应用授予所有相关权限,且尝试了两个拥有活跃OneDrive的微软账户,但问题依然存在。


可能的原因及解决方法

1. 权限未完成管理员同意

Files.ReadWrite.All这类委托权限需要租户管理员的明确同意才能生效,普通用户登录时无法自动获取该权限。

  • 登录Azure AD门户,进入应用注册→API权限页面,找到Files.ReadWrite.All权限,点击授予管理员同意按钮,确认权限状态变为已授予。

2. Access Token未包含目标作用域

即使登录时请求了权限,实际返回的Token可能未包含所需作用域(比如用户拒绝了权限请求)。

  • 用JWT解码工具解析Access Token,查看scp字段,确认是否包含Files.Read或Files.ReadWrite.All;
  • 简化作用域列表,只保留必要权限(比如User.Read和Files.Read.All),避免权限请求被部分拒绝。

3. 改用MSAL标准方式获取Token

直接使用loginPopup返回的Token可能存在受众(aud)不匹配的问题,推荐用acquireTokenSilent/acquireTokenPopup获取针对Graph API的Token:

// 修改initializeAuthProcess,传递instance而非token
export const initializeAuthProcess = async (instance) => {
    try {
      await instance.initialize();
      await instance.loginPopup({
        redirectUri: 'http://localhost:3000',
        scopes: ["User.Read", "Files.Read.All"],
        prompt: "select_account"
      });
      getData(instance);
    } catch (e) {
      console.error("initializeAuthProcess error", e);
    }
};

// 修改getData函数,用MSAL获取Token
async function getData(instance) {
  try {
    // 优先静默获取Token
    const tokenResponse = await instance.acquireTokenSilent({
      scopes: ["Files.Read.All"],
      account: instance.getAllAccounts()[0]
    });
    const client = Client.init({
      authProvider: (done) => done(null, tokenResponse.accessToken),
    });
    const data = await client.api('/me/drive/root/children').get();
    console.log("data", data);
  } catch (error) {
    // 静默失败则弹出窗口获取
    if (error.name === "InteractionRequiredAuthError") {
      const tokenResponse = await instance.acquireTokenPopup({
        scopes: ["Files.Read.All"]
      });
      // 重复请求逻辑
      const client = Client.init({
        authProvider: (done) => done(null, tokenResponse.accessToken),
      });
      const data = await client.api('/me/drive/root/children').get();
      console.log("data", data);
    }
    console.error("getData error", error);
  }
}

4. 验证OneDrive账户状态

部分新创建的账户未首次登录OneDrive网页版时,Graph API可能无法访问其Drive资源。

  • 让用户先登录https://onedrive.live.com,确认能正常查看文件后再测试应用。

5. 检查应用注册权限配置

  • 确保添加的是Microsoft Graph的权限,而非其他API;
  • 删除冗余或错误的权限条目,避免权限冲突。

内容的提问来源于stack exchange,提问作者Vaibhav Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:14:56