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

Nodemailer搭配OAuth2发邮件报No refresh token或refresh handler未设置错误

你遇到的报错核心原因是调用oAuth2Client.getAccessToken()时,OAuth2客户端没有识别到有效的refresh_token,可按照以下步骤排查修复:

  • 第一步:排查环境变量加载问题
    先在oAuth2Client.setCredentials代码行前加一行打印console.log('refresh token: ', process.env.REFRESH_TOKEN),运行代码看输出是否为undefined。

    • 本地环境如果使用dotenv管理环境变量,需要确保项目入口文件最顶部已经引入并初始化dotenv:require('dotenv').config(),且.env文件放在项目根目录,包含REFRESH_TOKEN等所有配置项。
    • 部署到Heroku时需要在控制台的设置页,手动配置所有环境变量,不要将.env文件提交到代码仓库。
  • 第二步:修正代码冗余和错误配置
    你当前的代码有两处多余配置:一是OAuth2认证不需要传pass参数,该参数是普通账号密码登录时使用的;二是创建transport不需要套smtTransport,直接给nodemailer传配置即可。修正后的核心代码参考:

const oAuth2Client = new google.auth.OAuth2(
  process.env.CLIENT_ID,
  process.env.CLIENT_SECRET,
  process.env.REDIRECT_URI
);
oAuth2Client.setCredentials({ refresh_token: process.env.REFRESH_TOKEN });

// transport可以全局创建,不需要每次发邮件都新建
const transport = nodemailer.createTransport({
  service: "gmail",
  auth: {
    type: "OAuth2",
    user: "kediaarts@gmail.com",
    clientId: process.env.CLIENT_ID,
    clientSecret: process.env.CLIENT_SECRET,
    refreshToken: process.env.REFRESH_TOKEN,
  }
});

const sendMail = async (email, code) => {
  try {
    const accessToken = await oAuth2Client.getAccessToken();
    // 动态给transport设置最新的accessToken
    transport.set('oauth2.accessToken', accessToken);
    
    const link = `http://localhost:5000/${email}/${code.toString()}`;
    const mailOptions = {
      from: '"Horizons" <no-reply@gmail.com>',
      to: email,
      subject: "Please verify your Email",
      html: `<h1>Horizons</h1><br><h2>Hi,<br> Please click on the link to verify your email.</h2><br><a href="${link}">Click here to verify</a>`,
    }
    const result = await transport.sendMail(mailOptions);
    return result;
  } catch(error) {
    console.log(error);
  }
}
  • 第三步:验证refresh_token有效性
    如果环境变量正常加载还是报错,说明你的refresh_token已经失效:
    • Google Cloud控制台中如果你的应用处于「测试」状态,授权生成的refresh_token有效期只有7天,过期后需要重新走授权流程生成新的refresh_token。
    • 确认授权时已经勾选了Gmail发送权限,对应的scope为https://www.googleapis.com/auth/gmail.send,没有正确授权的refresh_token无法调用发信接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:18:04