Search code examples
javascriptnode.jsexpressgoogle-apidialogflow-es

Google Token has been expired or revoked


I'm trying to implement an app that will remind the user on his upcoming google calendar events. I have created google OAuth token successfully and my app was working fine. but suddenly i got this error "error: 'invalid_grant',error_description: 'Token has been expired or revoked.'". Here is my code:

const TOKEN_PATH = 'token.json';

const OAuth2 = google.auth.OAuth2;

const googleConfig = {
  clientId: 'xxxxxxxxxxx', 
  clientSecret: 'xxxxxxxxxxxxxxxx', 
  redirect: 'xxxxxxxxxxxxxxx/landingPage' 
};

function createConnection() {
  return new OAuth2(
    googleConfig.clientId,
    googleConfig.clientSecret,
    googleConfig.redirect
  );
}

const defaultScope = [
   'https://www.googleapis.com/auth/calendar.readonly'
];

function getConnectionUrl(auth) {

  return auth.generateAuthUrl({
    access_type: 'offline',
    prompt: 'consent', // access type and approval prompt will force a new refresh token to be made each time signs in
    scope: defaultScope

  });
}

function urlGoogle() {
  const auth = createConnection(); // this is from previous step
  const url = getConnectionUrl(auth);
  return url;
}

app.get('/', function (req, res) {
    const url = urlGoogle()
    return res.render("index", { loginLink: url });
});

 app.get('/landingPage', (req, res) => {
    const OAuth = createConnection()
    function getNewToken(OAuth) {
      OAuth.getToken(req.query.code, (err, token) => {
        if (err) return console.error('Error retrieving access token', err);
        OAuth.setCredentials(token);
        fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
          if (err) return console.error(err);
          console.log('Token stored to', TOKEN_PATH);
          callHFunction(OAuth)
        });
      });
      }
      // Check if we have previously stored a token.
    fs.readFile(TOKEN_PATH, (err, token) => {
      if (err) return getNewToken(OAuth);
      OAuth.setCredentials(JSON.parse(token));
      console.log(OAuth.credentials)
      callHFunction(OAuth)
    });
    res.sendFile(path.join(__dirname, "./landingPage.html"));
  });

Any idea of how to fix this?


Solution

  • The most common cause for

    error: 'invalid_grant'

    • the user revoked your access.
    • you have reached the maximum number of outstanding refresh tokens (50) makes sure to always store the newest.
    • your app is still in the testing phase. Refresh tokens expire after 7 - 14 days.

    In the event you get this error its best to make sure your application can handle it by prompting the user to authorize your application again.