4

Similar question to this, except those answers are outdated and not applicable to my current situation.

Here's my webapp's signin flow:

  • Log in with Google (forces prompt, gives offline approval)
  • I successfully get a profile back with an access token and a refresh token
  • I do a few bits and pieces, then use that refresh token to generate an access token and download the user's contact list

This was working fine (last tested a week ago) but today it's suddenly giving me:

 error: invalid_grant

I'm using Node's xoauth2 package, and this hasn't been updated since June so I can't see why this would suddenly be a problem now - unless Google has changed something on their end in the past week or so?

Sample of the code I'm using that calls the error:

  // User credentials - all verified working + correct
  xoauth2gen = xoauth2.createXOAuth2Generator({
      user: email,
      clientId: configAuth.googleAuth.clientID,
      clientSecret: configAuth.googleAuth.clientSecret,
      refreshToken: refresh
  });

  // SMTP/IMAP
  xoauth2gen.getToken(function(err, token){
      if(err){
          return console.log("XOAUTH2 Error: " + err);
      }
      if(type === "full"){
        cb(token);
      }
  });

Edit: For completeness, the scopes I'm using when generating the refresh token are:

app.get('/auth/google', 
  passport.authenticate('google', 
  { 
  scope : ['https://mail.google.com/', 
           'profile', 
           'email',
           'https://www.googleapis.com/auth/userinfo.profile', 
           'https://www.google.com/m8/feeds'],
          accessType: 'offline', 
          approvalPrompt: 'force' 
  }
));
Community
  • 1
  • 1
JVG
  • 20,198
  • 47
  • 132
  • 210
  • I had to redo [these steps](http://masashi-k.blogspot.com.br/2013/06/sending-mail-with-gmail-using-xoauth2.html) to get it through. – Jonatas Walker Dec 10 '15 at 11:00

3 Answers3

2

According to RFC 6749 invalid_grant is returned when:

The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.

Check this out here

Community
  • 1
  • 1
Bruno Casarotti
  • 623
  • 8
  • 23
  • Ok, but as mentioned in the question the client id and secret are identical for generating the refresh token as well as requesting the access token... – JVG Dec 01 '15 at 19:03
  • Is your client id and secret the same? If so, why? Usually they are different aren't they? Which scopes are you requesting? – Bruno Casarotti Dec 01 '15 at 19:10
  • Scopes are in the OP. The ID !== the Secret, but the id and secret used for the access token request === the secret and id for the original authentication. – JVG Dec 01 '15 at 19:15
  • when asking for an access token, if I'm not wrong, you should also ask for the scope: client_id. Try to include that one as well – Bruno Casarotti Dec 01 '15 at 19:17
  • Also, [here](https://tools.ietf.org/html/rfc6749#section-3.1.1) you can have some insight, I believe that you are missing some parameter when requesting an access token – Bruno Casarotti Dec 01 '15 at 19:26
1

This was eventually fixed by deauthorizing my app in my Gmail account, deleting the refresh token I had stored in MongoDB and starting from scratch. Appears that it was simply a case of some permissions that I had changed, that hadn't been granted via oAuth2.

JVG
  • 20,198
  • 47
  • 132
  • 210
  • we are experiencing the same issue but not seems to be related to the permission changes, since we haven't made changes in the permissions – KumailR Nov 22 '19 at 13:20
0

If you are running a test server using localhost, this error may occur if your system time(OS time) is out of sync.

My system clock was not correct as my CMOS battery was dead. Every time I restarted my laptop the time would not be correct. Hence I would get this error when running

`node server.js'

and then making a request from the frontend to my express js backend

Rezwan Azfar Haleem
  • 1,198
  • 13
  • 23