使用Nodemailer+Gmail发送邮件时遭遇凭证错误求助
问题描述
基于React搭建的项目,联系表单提交时需向客户发送邮件,但始终出现凭证错误。项目结构:sendemail.js、服务端文件与.env文件位于根目录,联系表单在组件目录中,邮箱凭证存储在.env内。本地运行正常,重构适配服务器后出现该问题。
已尝试的解决方法:
- 更换凭证
- 使用谷歌身份验证器代码
- 关闭两步验证并使用普通密码填写到
.env文件
相关代码
sendemail.js
const nodemailer = require('nodemailer'); const sendEmail = async (formData) => { // Create a transporter using your email service provider's settings const transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: process.env.REACT_APP_SMTP_USER, // Ensure these are set in your .env pass: process.env.REACT_APP_SMTP_PASSWORD, // App-Specific Password for Gmail } }); // Setup email data const mailOptions = { from: process.env.REACT_APP_SMTP_USER, // Match this with the SMTP_USER to: formData.email, subject: formData.subject, text: `Name: ${formData.name}\nEmail: ${formData.email}\nMessage: ${formData.message}`, }; // Attempt to send the email try { const info = await transporter.sendMail(mailOptions); console.log('Email sent: ' + info.response); } catch (error) { console.error('Error sending email:', error); throw error; // Consider handling this more gracefully } }; module.exports = sendEmail;
服务端文件
const express = require('express'); const sendEmail = require('./sendEmail'); const app = express(); const cors = require('cors'); const port = process.env.PORT || 3001; const allowedOrigins = ['https://lashesbyjess.net', 'http://localhost:3000']; app.use(cors({ origin: function (origin, callback) { if (!origin || allowedOrigins.indexOf(origin) !== -1) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } } })); app.use(express.json()); app.post('/api/send-email', async (req, res) => { const formData = req.body; try { await sendEmail(formData); res.status(200).send('Email sent successfully'); } catch (error) { console.error('Error sending email:', error); res.status(500).send('Internal Server Error'); } }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
解决方案
1. 确认服务器环境变量配置
本地开发时React会自动加载.env,但服务器环境(如Vercel、Netlify、云服务器等)不能直接上传.env文件,需手动在平台配置面板添加REACT_APP_SMTP_USER和REACT_APP_SMTP_PASSWORD:
- 确保变量值与本地完全一致,无多余空格或特殊字符
- 若用PM2等进程管理器启动服务,需确保环境变量注入生效,可通过启动命令指定:
REACT_APP_SMTP_USER=你的邮箱 REACT_APP_SMTP_PASSWORD=你的密码 node server.js
2. 修正Gmail SMTP验证逻辑
Gmail已禁用普通密码用于SMTP登录,必须使用应用专用密码:
- 先开启谷歌账号的两步验证(必填前提)
- 进入谷歌账号的应用专用密码设置页面,选择“邮件”作为应用、“其他”作为设备,生成16位无空格的专用密码
- 将该密码填入服务器环境变量的
REACT_APP_SMTP_PASSWORD字段
3. 验证环境变量是否正常读取
在服务端代码顶部添加日志,确认变量加载状态:
// 服务端文件顶部 console.log('SMTP_USER:', process.env.REACT_APP_SMTP_USER); console.log('SMTP_PASSWORD:', process.env.REACT_APP_SMTP_PASSWORD ? '已加载' : '未加载');
部署后查看服务器日志,若显示“未加载”,需重新检查平台环境变量的配置步骤。
4. 更换第三方SMTP服务(备选)
若Gmail限制过多,可改用SendGrid、Mailgun等第三方邮件服务,以SendGrid为例:
- 注册账号并获取API密钥
- 修改
sendemail.js的 transporter 配置:const transporter = nodemailer.createTransport({ host: 'smtp.sendgrid.net', port: 587, auth: { user: 'apikey', pass: process.env.REACT_APP_SENDGRID_API_KEY } }); - 在服务器配置对应环境变量即可
5. 检查服务器端口/防火墙限制
部分服务器会限制SMTP端口(587、465等),可在服务器上执行telnet smtp.gmail.com 587测试连通性,若无法连接,需联系服务商开放对应出站端口。
内容的提问来源于stack exchange,提问作者Forrest
相关产品推荐
相关产品推荐

