简体   繁体   English

Gmail、nodemailer、OATH2 刷新令牌不起作用

[英]Gmail, nodemailer, OATH2 refresh token not working

I've set up Nodemailer to work with Gmail using OAuth2.我已经将 Nodemailer 设置为使用 OAuth2 处理 Gmail。 It works fine until the access token expires.它可以正常工作,直到访问令牌过期。 At this point, despite having a refresh token, I get the following error message:此时,尽管有刷新令牌,但我收到以下错误消息:

{ 
    Error: Invalid status code 401
        at ClientRequest.req.on.res (xxxxxxxxxxx)
        at emitOne (events.js:96:13)
        at ClientRequest.emit (events.js:191:7)
        at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:522:21)
        at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)
        at TLSSocket.socketOnData (_http_client.js:411:20)
        at emitOne (events.js:96:13)
        at TLSSocket.emit (events.js:191:7)
        at readableAddChunk (_stream_readable.js:178:18)
        at TLSSocket.Readable.push (_stream_readable.js:136:10)
        at TLSWrap.onread (net.js:561:20)
      type: 'FETCH',
      sourceUrl: 'https://accounts.google.com/o/oauth2/token',
      code: 'EAUTH',
      command: 'AUTH XOAUTH2' 
}

Here's my code.这是我的代码。 I've also tried including the refresh token and access token in the initial nodemailer setup, as well as including the expiry date.我还尝试在初始 nodemailer 设置中包含刷新令牌和访问令牌,以及包含到期日期。 Each time I get the same result.每次我都得到相同的结果。

Nodemailer setup:节点邮件程序设置:

const nodemailer = require('nodemailer')

const transporter = nodemailer.createTransport({
    host: 'smtp.gmail.com',
    port: 465,
    secure: true,
    auth: {
        type: 'OAuth2',
        clientId: 'xxxxxxxxxx',
        clientSecret: 'xxxxxxxxxx'
    }

});

transporter.on('token', token => {
    console.log('A new access token was generated');
    console.log('User: %s', token.user);
    console.log('Access Token: %s', token.accessToken);
    console.log('Expires: %s', new Date(token.expires));
});

E-mail setup:电子邮件设置:

const mailOptions = {
    from: xxxxxxxxx,
    to: xxxxxxxxx,
    subject: 'Test Subject',
    text: 'This is a test',
    html: '<p>This is a test</p>',
    auth: {
        user: 'xxxxxxxxxxxx',
        refreshToken: 'xxxxxxxxxxxxx',
        accessToken: 'xxxxxxxxxxxxx'
    }
}

E-mail send电子邮件发送

transporter.sendMail(mailOptions, function(err, info){
    if(err){
        return console.log(err);
    }
    console.log('Message %s sent: %s', info.messageId, info.response)
})

Can anyone suggest what may be going wrong?任何人都可以建议可能出了什么问题吗?

Check this SO post to direct you about the discussion on "refresh token", see answers by RobKohr and Radioreve .检查此SO 帖子以指导您有关“刷新令牌”的讨论,请参阅RobKohrRadioreve 的答案。

And maybe this OAuth2 samples can help you to check the difference from your code.也许这个OAuth2示例可以帮助您检查与您的代码的差异。

Reference from Nodemailer site:来自 Nodemailer 站点的参考:

OAuth2 allows your application to store and use authentication tokens instead of actual login credentials. OAuth2 允许您的应用程序存储和使用身份验证令牌而不是实际的登录凭据。 This is great for security as tokens or valid only for specific actions and can be easily revoked thus, once stolen, can't to as much harm as actual account credentials.这对于令牌的安全性非常有用,或者仅对特定操作有效,并且可以轻松撤销,因此一旦被盗,不会像实际帐户凭据那样造成太大的伤害。 OAuth2 authentication in Nodemailer is mostly used with Gmail and G Suite (née Google Apps) even though there are other providers that support it as well. Nodemailer 中的 OAuth2 身份验证主要用于 Gmail 和 G Suite(原名 Google Apps),即使还有其他提供商也支持它。

Access Tokens needed for OAuth2 authentication are short lived so these need to be regenerated from time to time. OAuth2 身份验证所需的访问令牌是短暂的,因此需要不时重新生成这些令牌。 Nodemailer is able to use both 3LO and 2LO to automatically regenerate the tokens but you can also handle all token specific yourself. Nodemailer 能够同时使用 3LO 和 2LO 来自动重新生成令牌,但您也可以自己处理所有特定于令牌的令牌。

You can refer to this SO post for addition information.您可以参考此SO 帖子以获取更多信息。

I know i am too late on this post.我知道我在这篇文章上为时已晚。 But i came here as i was facing same issue yesterday.但我来到这里是因为我昨天面临同样的问题。 I have fixed the issue and the issue was a silly mistake which was not mentioned anywhere.我已经解决了这个问题,这个问题是一个愚蠢的错误,在任何地方都没有提到。

So issue was in the process to create refresh token and access token in the google playground page.所以问题是在谷歌游乐场页面中创建刷新令牌和访问令牌的过程中。 I selected correct scope ( https://mail.google.com ) but while creating code and refresh token i did not added my app client id and secret and google was taking a client id and secret of playground by default .我选择了正确的范围( https://mail.google.com ),但是在创建代码和刷新令牌时,我没有添加我的应用程序客户端 ID 和密码,谷歌默认使用客户端 ID 和操场密码 So be careful to add your app's client id and secret in the playground.因此,请小心在操场中添加您的应用程序的客户端 ID 和机密。

To add your client id and password.添加您的客户端 ID 和密码。 Click on right top corner setting button.单击右上角的设置按钮。 Click on checkbox saying use your own credentials and click on close.单击复选框说使用您自己的凭据,然后单击关闭。 now if we create access refresh token Google will ask permission for our app instead of Google Playground.现在,如果我们创建访问刷新令牌,Google 将请求我们的应用程序而不是 Google Playground 的许可。

It will resolve the 401 issue.它将解决 401 问题。 This was not mentioned anywhere on any card created.在创建的任何卡片上都没有提到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM