Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid token with invalid_grant after a week #2886

Closed
jamm3e3333 opened this issue Jan 23, 2022 · 3 comments
Closed

Invalid token with invalid_grant after a week #2886

jamm3e3333 opened this issue Jan 23, 2022 · 3 comments
Labels
priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@jamm3e3333
Copy link

Environment details

  • Node.js version: v12.22.8
  • npm version: 6.14.15
  • googleapis version: 72.0.0
  • googl-auth-library version: 7.0.4
  • environment variabels: clientId, clientSecret, redirectUri

Issues

  • google cloud functions are implemented and are using gmail service from googleapis and oAuth2Client from google-auth-library packages
  • tokens are created when login into a gmail service account and stored in a db from which are read when tokens are needed
  • tokens are refreshed every hour by setting a cron job on a cloud function that refreshes tokens
  • after a week tokens get invalid even after refreshing them every hour

Cloud functions used in application

cloud functions are deployed on gcp
functions 1) and 2) are triggered only once
on function 3) is set the cron job every hour
on function 4) is set the cron job every day

Functions used:

1) Login

  1. instantiate oAuth2Client
new googleAuth.OAuth2Client({ clientId, clientSecret, redirectUri })
  1. redirect to url to login into gmail service account
oAuth2Client.generateAuthUrl({
    access_type: 'offline‘,
    scope: ['profile‘, 'email‘, ‚https://www.googleapis.com/auth/gmail.modify']
})
  1. when the gmail is authorised, it’s redirected to the cloud function Handle oAuth2 Callback address with the query parameter code with which new tokens are received

2) Handle oAuth2 Callback

  1. instantiate oAuth2Client
new googleAuth.OAuth2Client({ clientId, clientSecret, redirectUri})
  1. call a method getToken on an instance of oAuth2Client and pass a parameter as a query parameter from request obtained from a login function
  2. the method returns a new token object ({access_token, expiry_date, id_token, refresh_token, token_type, scope}) which is stored in a database
  3. call method setCredentials on an instance oAuth2Client and pass created tokens as an argument
  4. call google.options({ auth: oAuth2Client }) so the gmail service can be used with the service account
  5. call watch method
gooogle.gmail( 'v1‘).users.watch({
    userId: email,
    requestBody: {
        labelIds: ['INBOX`], 
        topicName: PUBSUB_TOPIC,
        }
    })

variable email is passed from a method google.oauth2('v2‘)userinfo.get() and PUBSUB_TOPIC is set in a google console for the service account

3) Sync mails

  1. instantiate oAuth2Client
new googleAuth.OAuth2Client({ clientId, clientSecret, redirectUri})
  1. read stored tokens object from db
  2. call method setCredentials on an instance OAuth2Client and pass tokens as an argument
  3. call method getAccesToken on oAuth2Client instance to refresh tokens validity
  4. call google.options({auth: oAuth2Client})
  5. process messages from gmail service account

4) Refresh Watch

  1. instantiate oAuth2Client
new googleAuth.OAuth2Client({ clientId, clientSecret, redirectUri})
  1. read stored tokens object from db
  2. call method setCredentials on an instance OAuth2Client and pass tokens as an argument
  3. call method getAccesToken on oAuth2Client instance
  4. call google.options({auth: oAuth2Client})
  5. call watch method
gooogle.gmail('v1‘).users.watch({
    userId: email, 
    requestBody: {
        abelIds: ['INBOX`], 
        topicName: PUBSUB_TOPIC,
        }
    })

email is passed as a me string and PUBSUB_TOPIC is set in a google console for the service account

Steps done to try to fix the issue with invalid tokens

  • every time after creating a new intsance of oAuth2Client, call on method and listen on an event tokens to update tokens in db, but this didn't help
on.('tokens', (tokens) => {
    ...
})

Error that is showing up:

error: {
code: "400"
message: "invalid_grant"
stack: "Error: invalid_grant
    at Gaxios._request (/workspace/node_modules/gaxios/build/src/gaxios.js:129:23)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async OAuth2Client.refreshTokenNoCache (/workspace/node_modules/google-auth-library/build/src/auth/oauth2client.js:174:21)
    at async OAuth2Client.refreshAccessTokenAsync (/workspace/node_modules/google-auth-library/build/src/auth/oauth2client.js:198:19)
    at async OAuth2Client.getAccessTokenAsync (/workspace/node_modules/google-auth-library/build/src/auth/oauth2client.js:227:23)"
}
@jamm3e3333 jamm3e3333 added priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Jan 23, 2022
@LindaLawton
Copy link

Apps that are in test have their refresh tokens expired after seven days.

To fix it up your application into production.

Refresh token

A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.

@jmsmistral
Copy link

jmsmistral commented Apr 23, 2023

I must say that this is very annoying.
I have a very simple node app that I run locally to download some data from a Google Sheet I update with cost transactions. It just saves me having to copy and paste the data to an Excel. It worked when I first set it up, but it doesn't any more because of this issue.

Now to lift this 7-day limit, I have to:

  • publish the app to production
  • go through an entire verification process that could take 3-6 weeks
  • provide links to a web page with privacy related verbiage of how I am using the data
  • create a Youtube video explaining about the scope usage

It's only me using this app :(

@frontBOI
Copy link

I must say this is very annoying procedure. Could you please increase this limit to six month ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

No branches or pull requests

4 participants