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

使用Nodemailer+Office 365 OAuth2发邮件遇令牌创建错误求助

问题分析与解决步骤

出现Can't create new access token for user错误,大概率是OAuth2配置不完整、权限未正确配置或TLS参数错误导致的,以下是具体排查和修复方案:


1. 先修复TLS配置错误

你的代码中设置了tls: { ciphers: 'SSLv3' },但Office 365 SMTP服务已废弃SSLv3协议,这会直接导致TLS握手失败,间接影响令牌请求。必须删除这个配置项,使用Nodemailer默认的TLS cipher即可。


2. 完善OAuth2配置(分两种场景)

Office 365的SMTP OAuth2支持两种授权流,你需要根据自己的使用场景补充对应参数:

场景1:授权码流(针对单个用户邮箱)

适合需要用特定用户身份发送邮件的场景,需要用户完成授权流程获取刷新令牌:

const config: Options = {
  service: 'office365', // 配置service后可省略host/port/secure参数
  requireTLS: true,
  auth: {
    type: 'OAuth2',
    user: this.configService.get<string>('mail.senderMail'),
    clientId: clientId,
    clientSecret: clientSecret,
    refreshToken: '你的刷新令牌', // 必须补充,Nodemailer会自动用它刷新access token
    scope: 'https://outlook.office365.com/SMTP.Send', // 对应SMTP发送权限
    accessUrl: 'https://login.microsoftonline.com/2XXXXXXXXXXXXXX/oauth2/v2.0/token',
  },
};

前置要求:

  • 在Azure AD注册应用时,添加Delegated权限:SMTP.Send或Mail.Send
  • 完成授权码流程,获取有效的refreshToken

场景2:客户端凭证流(应用级权限,无需用户授权)

适合服务端后台发送邮件的场景,需要管理员授予应用权限:

const config: Options = {
  service: 'office365',
  requireTLS: true,
  auth: {
    type: 'OAuth2',
    user: this.configService.get<string>('mail.senderMail'), // 发送邮件的邮箱地址
    clientId: clientId,
    clientSecret: clientSecret,
    grant_type: 'client_credentials', // 必须指定客户端凭证流类型
    scope: 'https://outlook.office365.com/.default', // 应用权限需使用.default scope
    accessUrl: 'https://login.microsoftonline.com/2XXXXXXXXXXXXXX/oauth2/v2.0/token',
  },
};

前置要求:

  • 在Azure AD注册应用时,添加Application权限:SMTP.Send或Mail.Send
  • 由租户管理员完成权限同意操作

3. 额外检查项

  • 确认accessUrl中的租户ID(2XXXXXXXXXXXXXX)正确,商业版Office 365必须使用租户ID,个人账号可替换为common
  • 检查Azure AD应用的重定向URI、权限范围是否与授权流程一致
  • 确保clientId和clientSecret没有拼写错误或过期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:57:54