Node.js后端通过Graph API认证O365账户并发邮件:已获AccessToken但无法发件
Node.js后端通过Graph API发送O365邮件的解决方案
你已经拿到AccessToken但无法发邮件,大概率是权限配置、请求格式或Token有效性的问题,以下是针对性的排查和解决步骤:
1. 确认权限配置是否正确
- 如果是后端服务(Daemon模式),必须使用应用权限:
- 在Azure AD应用注册中,添加
Mail.Send的应用权限,并由管理员完成管理员同意 - 获取Token时,
scope参数必须设为https://graph.microsoft.com/.default(应用权限的固定scope格式)
- 在Azure AD应用注册中,添加
- 如果是用户委托模式(后端模拟用户操作),
scope需设为Mail.Send,且用户已授权该权限
2. 验证AccessToken的有效性
用JWT解析工具检查Token内容:
aud字段必须是https://graph.microsoft.com(确保Token是给Graph API用的)- 应用权限模式下,
roles数组中需包含Mail.Send - 委托权限模式下,
scp字段需包含Mail.Send
3. 正确调用Graph API发送邮件
核心要求:
- API端点:
POST https://graph.microsoft.com/v1.0/users/{sender-id}/sendMailsender-id可以是发送者的邮箱地址或Azure AD对象ID(应用权限模式下必须指定发送者,因为服务本身不能直接发邮件)
- 请求头必须包含:
Authorization: Bearer {your-access-token}Content-Type: application/json
- 请求体格式示例:
{ "message": { "subject": "测试邮件", "body": { "contentType": "HTML", "content": "<p>这是通过Graph API发送的测试邮件</p>" }, "toRecipients": [ { "emailAddress": { "address": "recipient@example.com" } } ] }, "saveToSentItems": true }
Node.js代码示例(用axios)
const axios = require('axios'); async function sendO365Email(accessToken, senderEmail, recipientEmail) { try { const res = await axios.post( `https://graph.microsoft.com/v1.0/users/${encodeURIComponent(senderEmail)}/sendMail`, { message: { subject: 'Graph API 测试邮件', body: { contentType: 'HTML', content: '<h3>测试内容</h3><p>这是来自Node.js后端的邮件</p>' }, toRecipients: [ { emailAddress: { address: recipientEmail } } ] }, saveToSentItems: true }, { headers: { 'Authorization': `Bearer ${accessToken}`, 'Content-Type': 'application/json' } } ); console.log('邮件发送成功,状态码:', res.status); } catch (err) { console.error('发送失败:', err.response?.data || err.message); // 常见错误:403=权限不足,401=Token无效/过期,400=请求体格式错误 } } // 替换为你的实际参数 sendO365Email('你的AccessToken', 'sender@yourdomain.com', 'recipient@example.com');
4. 常见错误排查
- 403 Forbidden:检查Azure AD应用是否已获得
Mail.Send权限且完成管理员同意;确认Token中的roles/scp包含该权限 - 401 Unauthorized:检查Token是否过期,
aud字段是否为https://graph.microsoft.com - 400 Bad Request:检查请求体的JSON格式是否正确,比如字段拼写错误、邮箱格式无效
内容的提问来源于stack exchange,提问作者Ravi
相关产品推荐
相关产品推荐

