如何使用Node.JS和委托权限从Office365获取邮件?
解决Node.js通过委托权限访问Office365邮箱邮件的问题
核心问题定位
- Scope使用错误:委托权限场景下不能用
https://graph.microsoft.com/.default,这个scope仅适用于应用级权限。委托权限需要指定具体的Delegated类型权限,比如Mail.Read、Mail.Read.Shared(访问共享邮箱时)。 - 应用注册配置缺失:
InteractiveBrowserCredential和DeviceCodeCredential属于公共客户端流程,需要正确配置应用注册的重定向URI、权限类型及同意状态。
分步解决方案
1. 修正Azure AD应用注册配置
- 进入Azure AD应用注册,在身份验证页面:
- 添加对应流程的重定向URI:
InteractiveBrowserCredential:添加http://localhost:3000/redirect(本地开发用,需和代码一致)DeviceCodeCredential:无需重定向URI,但要确保应用被标记为公共客户端(在“高级设置”里开启“允许公共客户端流”)
- 添加对应流程的重定向URI:
- 在权限页面:
- 添加Delegated类型的Microsoft Graph权限,比如
Mail.Read、Mail.Read.Shared(根据需求选择) - 点击“授予管理员同意”(租户级生效,或让用户在登录时自行同意)
- 添加Delegated类型的Microsoft Graph权限,比如
2. 正确使用InteractiveBrowserCredential获取Token并访问邮件
安装依赖:
npm install @azure/identity @microsoft/microsoft-graph-client isomorphic-fetch
示例代码:
const { InteractiveBrowserCredential } = require("@azure/identity"); const { Client } = require("@microsoft/microsoft-graph-client"); require("isomorphic-fetch"); async function getEmails() { // 配置凭据,注意scope用具体的Delegated权限 const credential = new InteractiveBrowserCredential({ clientId: "你的应用客户端ID", tenantId: "你的租户ID", redirectUri: "http://localhost:3000/redirect" // 和应用注册里的一致 }); const scopes = ["https://graph.microsoft.com/Mail.Read"]; const accessToken = await credential.getToken(scopes); // 初始化Graph客户端 const client = Client.init({ authProvider: (done) => { done(null, accessToken.token); } }); // 获取当前用户邮件,若要访问特定邮箱,替换为/users/{邮箱ID或UPN}/messages const messages = await client.api("/me/messages").top(10).get(); console.log(messages); } getEmails().catch(err => console.error(err));
3. 正确使用DeviceCodeCredential获取Token并访问邮件
示例代码:
const { DeviceCodeCredential } = require("@azure/identity"); const { Client } = require("@microsoft/microsoft-graph-client"); require("isomorphic-fetch"); async function getEmails() { const credential = new DeviceCodeCredential({ clientId: "你的应用客户端ID", tenantId: "你的租户ID", // 自定义设备码提示信息 userPromptCallback: (info) => { console.log(info.message); } }); const scopes = ["https://graph.microsoft.com/Mail.Read"]; const accessToken = await credential.getToken(scopes); const client = Client.init({ authProvider: (done) => { done(null, accessToken.token); } }); // 访问特定邮箱示例 const targetMailboxId = "目标邮箱的UPN或ID"; const messages = await client.api(`/users/${targetMailboxId}/messages`).top(10).get(); console.log(messages); } getEmails().catch(err => console.error(err));
4. 解决“访问被拒绝”的额外注意事项
- 若要访问其他用户的邮箱,需确保当前登录用户拥有该邮箱的访问权限(比如管理员设置了代理访问,或邮箱已共享给当前用户),同时使用
Mail.Read.Shared或Mail.ReadWrite.Shared权限。 - 检查Token权限:解析Token的
scp字段,确认包含你申请的权限项。
内容的提问来源于stack exchange,提问作者Shashank Varanasi
相关产品推荐
相关产品推荐

