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

Google Cloud OAuth2场景下nodemailer发信报530认证错误

Nodemailer对接Gmail OAuth2发信报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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:01:09