简体   繁体   中英

Gmail, nodemailer, OATH2 refresh token not working

I've set up Nodemailer to work with Gmail using OAuth2. 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. 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 .

And maybe this OAuth2 samples can help you to check the difference from your code.

Reference from Nodemailer site:

OAuth2 allows your application to store and use authentication tokens instead of actual login credentials. 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.

Access Tokens needed for OAuth2 authentication are short lived so these need to be regenerated from time to time. Nodemailer is able to use both 3LO and 2LO to automatically regenerate the tokens but you can also handle all token specific yourself.

You can refer to this SO post for addition information.

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 . So be careful to add your app's client id and secret in the playground.

To add your client id and password. 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.

It will resolve the 401 issue. This was not mentioned anywhere on any card created.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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