Nodemailer+OAuth认证失败:535-5.7.8登录无效错误求助
Nodemailer 发送邮件触发 535-5.7.8 认证失败错误
配置Nodemailer发送邮件时,出现Error: Invalid login: 535-5.7.8 Username and Password not accepted错误。此前功能正常,更换公司账号测试后,原个人账号也无法使用。已重新创建OAuth客户端ID、通过OAuth Playground获取凭证,但问题依旧。能成功获取access token,但发送邮件时认证失败。
报错信息
Successfully retrieved access token <an up to date access token> Error sending email: Error: Invalid login: 535-5.7.8 Username and Password not accepted. For more information, go to 535 5.7.8 https://support.google.com/mail/?p=BadCredentials 8926c6da1cb9f-4ec7458ef79sm1016661173.14 - gsmtp at SMTPConnection._formatError (C:\Users\Build\code\projxon\business-data-association\backend\node_modules\nodemailer\lib\smtp-connection\index.js:807:19) at SMTPConnection._actionAUTHComplete (C:\Users\Build\code\projxon\business-data-association\backend\node_modules\nodemailer\lib\smtp-connection\index.js:1586:34) at SMTPConnection.<anonymous> (C:\Users\Build\code\projxon\business-data-association\backend\node_modules\nodemailer\lib\smtp-connection\index.js:1565:26) at SMTPConnection._processResponse (C:\Users\Build\code\projxon\business-data-association\backend\node_modules\nodemailer\lib\smtp-connection\index.js:991:20) at SMTPConnection._onData (C:\Users\Build\code\projxon\business-data-association\backend\node_modules\nodemailer\lib\smtp-connection\index.js:772:14) at SMTPConnection._onSocketData (C:\Users\Build\code\projxon\business-data-association\backend\node_modules\nodemailer\lib\smtp-connection\index.js:195:44) at TLSSocket.emit (node:events:524:28) at addChunk (node:internal/streams/readable:561:12) at readableAddChunkPushByteMode (node:internal/streams/readable:512:3) at Readable.push (node:internal/streams/readable:392:5) { code: 'EAUTH', response: '535-5.7.8 Username and Password not accepted. For more information, go to\n' + '535 5.7.8 https://support.google.com/mail/?p=BadCredentials 8926c6da1cb9f-4ec7458ef79sm1016661173.14 - gsmtp', responseCode: 535, command: 'AUTH XOAUTH2' }
相关代码
import express from "express"; import cors from "cors"; import nodemailer from "nodemailer"; import dotenv from "dotenv"; import { google } from "googleapis"; dotenv.config(); const app = express(); app.use(cors()); app.use(express.json()); const OAuth2Client = new google.auth.OAuth2( process.env.EMAIL_CLIENT_ID, process.env.EMAIL_CLIENT_SECRET, process.env.EMAIL_REDIRECT_URI ); OAuth2Client.setCredentials({ refresh_token: process.env.EMAIL_REFRESH_TOKEN, }); const getAccessToken = async () => { try { const { token } = await OAuth2Client.getAccessToken(); if (!token) { throw new Error('No access token retrieved'); } console.log("Successfully retrieved access token", token); return token; } catch (error) { console.error("Failed to create access token:", error); throw new Error("Failed to create access token."); } }; const createTransporter = async () => { const accessToken = await getAccessToken(); if (!accessToken) throw new Error("Failed to get access token"); return nodemailer.createTransport({ service: "gmail", auth: { type: "OAuth2", user: process.env.EMAIL_USER, clientId: process.env.EMAIL_CLIENT_ID, clientSecret: process.env.EMAIL_CLIENT_SECRET, refreshToken: process.env.EMAIL_REFRESH_TOKEN, accessToken, }, }); }; app.post("/send-email", async (req, res) => { const { name, email, message } = req.body; const mailOptions = { from:{process.env.EMAIL_USER}, to: email, subject: "Thank Youn!", text: `Hi ${name}`, replyTo: process.env.EMAIL_USER, }; try { const transporter = await createTransporter(); await transporter.sendMail(mailOptions); res.status(200).json({ message: "Email sent successfully!" }); } catch (error) { console.error("Error sending email:", error); if (error.responseCode === 535) { res.status(401).json({ error: "Authentication error. Please check your credentials." }); } else { res.status(500).json({ error: "Error sending email. Please try again later." }); } } }); const PORT = process.env.PORT || 5000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
已尝试方案
- 重新创建OAuth客户端凭证
- 本地测试个人及公司账号
解决办法
1. 确认OAuth权限范围
在Google Cloud控制台或OAuth Playground中,为客户端ID添加https://mail.google.com/权限范围——这是Gmail发送邮件所需的完整权限,仅用https://www.googleapis.com/auth/gmail.send可能导致认证失败。
2. 刷新令牌有效性校验
更换账号后旧刷新令牌会失效,需:
- 重新在OAuth Playground中授权目标账号,获取最新刷新令牌
- 核对
.env文件中EMAIL_REFRESH_TOKEN与新令牌完全一致
3. 检查账号安全设置
- 个人账号:确认是否开启了第三方应用访问权限(OAuth2虽不强制,但部分场景可能受影响)
- 公司账号:联系管理员确认是否有安全策略限制第三方应用发送邮件
4. 修正代码语法错误
mailOptions中from字段写法错误,且存在笔误,修正如下:
const mailOptions = { from: process.env.EMAIL_USER, // 或完整对象格式:{ name: "自定义名称", address: process.env.EMAIL_USER } to: email, subject: "Thank You!", // 修正笔误:Youn → You text: `Hi ${name}`, replyTo: process.env.EMAIL_USER, };
5. 移除旧授权记录
访问Google账号的第三方应用管理页面,删除旧的客户端授权记录,重新授权获取刷新令牌。
6. 交由Nodemailer自动管理令牌
无需手动获取access token,Nodemailer可自动处理令牌刷新,修改createTransporter函数:
const createTransporter = () => { return nodemailer.createTransport({ service: "gmail", auth: { type: "OAuth2", user: process.env.EMAIL_USER, clientId: process.env.EMAIL_CLIENT_ID, clientSecret: process.env.EMAIL_CLIENT_SECRET, refreshToken: process.env.EMAIL_REFRESH_TOKEN, }, }); };
内容的提问来源于stack exchange,提问作者EvanPrograms
相关产品推荐
相关产品推荐

