Google Cloud OAuth2场景下nodemailer发信报530认证错误
问题背景
- 此前已成功配置2个Gmail账号,实现Node.js应用内通过nodemailer对接Google Cloud提供的OAuth2能力完成邮件发送,首次配置时应用发信功能正常
- 本次按照完全相同的步骤完成配置后,尝试发信时抛出异常,核心错误信息如下:
Error: Mail command failed: 530-5.7.0 Authentication Required
- 网上部分解决方案提出需要开启Google账号的*less secure app(低安全性应用访问)*权限,但该选项已于2022年5月被Google官方下线,无法通过该路径解决问题
本次Google Cloud OAuth2配置流程
本次配置完全沿用此前验证可行的标准流程,操作如下:
- 创建new project(新项目)
- 启用所需的服务与API
- 在OAuth consent screen(OAuth同意屏幕)页面新建OAuth2配置
- 创建Web应用类型的新凭证,配置重定向地址为:
https://developers.google.com/oauthplayground - 在OAuth同意屏幕页面添加test users(测试用户)
- 进入oauthplayground平台,选择
https://mail.google.com服务,填入CLIENT_ID与CLIENT_SECRET后,点击Exchange authorization code for tokens(授权码兑换令牌) - 配置完成后已将CLIENT_ID、CLIENT_SECRET、refresh_tokens等所有必填参数同步到Node.js项目中
项目核心代码
邮件发送逻辑代码
const nodemailer = require('nodemailer'); const urlUtil = require('../utils/urlUtil'); const config = require(urlUtil.getPath('../config.min.js')); const googleApiUtil = require(urlUtil.getPath('../utils/googleApiUtil.min.js')); /** * Send generic email * @param {*} destination to * @param {*} subject title of the email * @param {*} html html content for email template * @returns promise */ function sendEmail(destination, subject, html) { return new Promise((resolve) => { googleApiUtil.getCredentials().then((credentials) => { try { let transporter = nodemailer.createTransport({ service: config.mail.service, auth: { type: 'OAuth2', user: config.mail.user, clientId: credentials.client_id, clientSecret: credentials.client_secret, refreshToken: credentials.refresh_token, accessToken: credentials.accessToken }, tls: { rejectUnauthorized: false } }); let mailOptions = {}; mailOptions = { from: `IARA <${config.mail.user}>`, to: destination, subject: subject, html: html, attachments: null }; transporter.sendMail(mailOptions, resolve); } catch (error) { console.log(error); } }); }); } //This should send an email to destinantion sendEmail('adriel.kirch.1@gmail.com','teste','testando').then(r=> { console.log(r) }) /** * Exports */ module.exports = { sendEmail };
Google OAuth2鉴权工具代码
const {google} = require('googleapis'); const urlUtil = require('../utils/urlUtil'); const config = require(urlUtil.getPath('../config.min.js')); const fsUtil = require(urlUtil.getPath('../utils/fsUtil.min.js')); //Basic credentials const CLIENT_ID = '4123123..'; const CLIENT_SECRET = 'GO...'; //https://developers.google.com/oauthplayground const REDIRECT_URI = 'https://developers.google.com/oauthplayground'; let refresh_token = ''; let accessToken = ''; if (!config.mail.refresh_token) { refresh_token = '1//...'; } else { refresh_token = config.mail.refresh_token; } const oAuth2Client = new google.auth.OAuth2(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI); oAuth2Client.setCredentials({ refresh_token: refresh_token, }); oAuth2Client.refreshAccessToken((err, tokens) => { console.log(tokens) accessToken = tokens['access_token']; refresh_token = tokens['refresh_token']; //Set Config if (err) { console.log(err); } config.mail.accessToken = accessToken; config.mail.refresh_token = refresh_token; fsUtil.updateCredentials(config); }); /** * @returns Get credentials */ async function getCredentials() { return { redirect_uri: REDIRECT_URI, refresh_token: refresh_token, client_id: CLIENT_ID, client_secret: CLIENT_SECRET, accessToken: accessToken }; } module.exports = { getCredentials };
问题现状
目前无法定位问题出在OAuth2配置环节还是Nodejs代码逻辑,初步推测可能是Google Cloud侧的配置问题,寻求有相关开发经验的开发者提供解决方案。
完整错误栈信息如下:
Error: Mail command failed: 530-5.7.0 Authentication Required. Learn more at
530 5.7.0 https://support.google.com/mail/?p=WantAuthError dy43-20020a056870c7ab00b00101cdb417f1sm5627633oab.22 - gsmtp
at SMTPConnection._formatError (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:784:19)
at SMTPConnection._actionMAIL (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:1566:34)
at SMTPConnection.(c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:1041:18)
at SMTPConnection._processResponse (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:947:20)
at SMTPConnection._onData (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:749:14)
at TLSSocket.SMTPConnection._onSocketData (c:\Javascript Projects\IARA-backend\node_modules\nodemailer\lib\smtp-connection\index.js:189:44)
at TLSSocket.emit (events.js:315:20)
at addChunk (internal/streams/readable.js:309:12)
at readableAddChunk (internal/streams/readable.js:284:9)
at TLSSocket.Readable.push (internal/streams/readable.js:223:10) {
code: 'EENVELOPE',
response: '530-5.7.0 Authentication Required. Learn more at\n' +
'530 5.7.0 https://support.google.com/mail/?p=WantAuthError dy43-20020a056870c7ab00b00101cdb417f1sm5627633oab.22 - gsmtp',
responseCode: 530,
command: 'MAIL FROM'
}
内容的提问来源于stack exchange,提问作者Iara Gerencia

