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

使用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登录,必须使用应用专用密码:

  1. 先开启谷歌账号的两步验证(必填前提)
  2. 进入谷歌账号的应用专用密码设置页面,选择“邮件”作为应用、“其他”作为设备,生成16位无空格的专用密码
  3. 将该密码填入服务器环境变量的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为例:

  1. 注册账号并获取API密钥
  2. 修改sendemail.js的 transporter 配置:
    const transporter = nodemailer.createTransport({
      host: 'smtp.sendgrid.net',
      port: 587,
      auth: {
        user: 'apikey',
        pass: process.env.REACT_APP_SENDGRID_API_KEY
      }
    });
    
  3. 在服务器配置对应环境变量即可

5. 检查服务器端口/防火墙限制

部分服务器会限制SMTP端口(587、465等),可在服务器上执行telnet smtp.gmail.com 587测试连通性,若无法连接,需联系服务商开放对应出站端口。


内容的提问来源于stack exchange,提问作者Forrest

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:42:19