Google停用低安全应用选项后如何用Nodemailer发送Gmail邮件
可行解决方案
Google 下线低安全应用访问权限后,直接使用账号密码登录Gmail SMTP的鉴权方式已经失效,以下是三种经过验证的可用方案,按改造成本从低到高排序:
方案一:应用专用密码(单账号发信首选,改动最小)
该方案是Google官方为第三方邮件客户端提供的标准鉴权方式,几乎不需要修改原有业务逻辑,仅需调整鉴权参数即可:
- 前置要求:发信使用的Google账号必须已开启两步验证,未开启两步验证的账号不会显示应用专用密码入口
- 操作步骤:
- 登录对应Google账号,进入安全设置页,开启两步验证并完成身份校验
- 在安全设置页找到「应用专用密码」入口,选择应用类型为「邮件」,设备类型按需选择,点击生成后会得到16位长度的专用密码
- 修改
nodemailer的传输配置,将原配置中的账号密码替换为邮箱地址+刚生成的16位应用专用密码即可
- 修正后的可运行代码:
const nodemailer = require('nodemailer') const sendEmail = async options => { const transporter = nodemailer.createTransport({ host: "smtp.gmail.com", port: 465, secure: true, auth: { user: process.env.GMAIL_ADDRESS, // 你的Gmail完整邮箱地址 pass: process.env.GMAIL_APP_PASSWORD // 16位应用专用密码,不要填原账号登录密码 } }) const message = { from: `${process.env.FROM_NAME} <${process.env.FROM_EMAIL}>`, to: options.email, subject: options.subject, text: options.message, html: options.message, attachments: [ { filename: 'notify.png', // 补全实际附件文件名,原代码此处为空会导致附件异常 path: __dirname + '/notify.png', // 补全路径斜杠,避免拼接出错误文件路径 cid: 'notify.png' } ] } const info = await transporter.sendMail(message) console.log('Message sent : %s', info.messageId) } module.exports = sendEmail
注意:原代码中的tls:{rejectUnauthorized:false}会跳过证书校验,存在中间人攻击风险,生产环境建议移除。敏感凭据全部通过环境变量读取,不要硬编码在代码中。
方案二:OAuth2.0鉴权(多用户场景适用)
如果你的应用需要支持多个Gmail用户授权自己的账号发信,可使用Google官方的OAuth2.0鉴权流程,不需要用户开启两步验证:
- 操作步骤:
- 进入Google Cloud控制台创建项目,启用Gmail API服务
- 创建OAuth2.0客户端凭据,获取客户端ID、客户端密钥、重定向地址
- 引导用户完成OAuth授权流程,获取对应用户的刷新令牌
- 在
nodemailer的鉴权配置中传入OAuth2相关参数即可
- 鉴权配置示例:
auth: { type: 'OAuth2', user: '用户的Gmail邮箱地址', clientId: '你创建的OAuth客户端ID', clientSecret: '你创建的OAuth客户端密钥', refreshToken: '用户授权后获取的刷新令牌' }
方案三:第三方事务邮件服务(无需适配Google规则)
如果不想处理Google账号的鉴权限制、地区访问限制,可以直接替换为专业的事务邮件服务,这类服务普遍兼容SMTP协议,仅需修改SMTP连接配置即可,发信送达率也更有保障:
- 国内可选:阿里云邮件推送、腾讯云简单邮件服务
- 海外可选:SendGrid、Mailgun、Resend
常见踩坑提示:如果使用云服务器部署服务,注意确认服务器出口IP没有被25端口封禁,优先使用465/587端口发信。
内容的提问来源于stack exchange,提问作者Μελέτης Πέππας
相关产品推荐
相关产品推荐

