Nodemailer 和 Firebase Cloud Functions 的错误授权 OAuth2 无效

Posted

技术标签:

【中文标题】Nodemailer 和 Firebase Cloud Functions 的错误授权 OAuth2 无效【英文标题】:Error invalid grant OAuth2 with Nodemailer and Firebase Cloud Functions 【发布时间】:2021-06-15 04:31:35 【问题描述】:

我有下一个问题。我使用 NodeJs、Typescript、OAuth2、Gmail 在 Firebase 云功能中实现。我遵循了一个类似的教程 https://dev.to/chandrapantachhetri/sending-emails-securely-using-node-js-nodemailer-smtp-gmail-and-oauth2-g3a

我将附上下面的代码。问题是刷新令牌以某种方式被撤销或过期,持续大约 8 天。我的解决方法是在https://developers.google.com/oauthplayground 中生成一个新的刷新令牌,如教程中所述,并且修复了大约 8 天的新访问令牌请求。我尝试了很多方法,但都没有成功。

云功能日志中提供的错误与此类似,还有很多其他人无法理解的事情


   error: 'invalid_grant',
   error_description: 'Token has been expired or revoked.' 

有人可以帮我解决这个问题吗?

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import * as nodemailer from "nodemailer";
import * as goole from "googleapis";
admin.initializeApp();

// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript

export const mailPedidos = functions.firestore
  .document("example/exampleId")
  .onCreate(async (snapshot, context) => 

    //business logic removed
    let name = "Carl";        
    let mail = "example@gmail.com";
    const mailOptions = 
      from: "Kuxon <fromExample@gmail.com>",
      to: mail,
      subject: "Example Subject",
      html: `<p style="font-size: 16px;">Name: $name </p>
            `, // email content in HTML
    ;

    try 
      const CLIENT_ID =
        "CLIENTID";
      const CLIENT_SECRET = "CLIENTSECRET";
      const REDIRECT_URI = "https://developers.google.com/oauthplayground";
      const REFRESH_TOKEN =
        "REFRESHTOKEN";

      const oAuth2Client = new goole.google.auth.OAuth2(
        CLIENT_ID,
        CLIENT_SECRET,
        REDIRECT_URI
      );
      oAuth2Client.setCredentials( refresh_token: REFRESH_TOKEN );

      const accessToken = await oAuth2Client.getAccessToken();
      console.log("Access Token: " + accessToken);

      let aT: string | undefined = "";

      if (accessToken.token !== null) 
        aT = accessToken.token;
      

      console.log("Access Token token: " + aT);

      const transporter = nodemailer.createTransport(
        service: "gmail",
        auth: 
          type: "OAuth2",
          user: "example@gmail.com",
          clientId: CLIENT_ID,
          clientSecret: CLIENT_SECRET,
          refreshToken: REFRESH_TOKEN,
          accessToken: aT,
        ,
      );

      // returning result
      transporter.sendMail(mailOptions, (error: any, info: any) => 
        if (error) 
          console.log(error.toString());
        
        console.log("Sended");
      );
     catch (error) 
      console.log( error );
    
    return snapshot;
  ); 

【问题讨论】:

【参考方案1】:

这可能是因为谷歌云平台的配置。

为外部用户类型配置了 OAuth 同意屏幕且发布状态为“正在测试”的 Google Cloud Platform 项目发出了一个在 7 天后到期的刷新令牌。

相关主题链接:Do google refresh tokens expire?

【讨论】:

以上是关于Nodemailer 和 Firebase Cloud Functions 的错误授权 OAuth2 无效的主要内容,如果未能解决你的问题,请参考以下文章

使用 Firebase Cloud Functions 时 Nodemailer 查询 A EREFUSED localhost

在 Firebase 云功能中通过 nodemailer 发送邮件是不是需要计费帐户?

与 Firebase 函数一起使用时,Nodemailer 无法正常工作

节点邮件错误

Firebase 函数环境变量无法读取未定义的属性

在firebase函数中启用CORS