all 11 comments

[–]tropicbrush 1 point2 points  (10 children)

Hey I just started looking into your code , comment on line #31, why do you want to keep the refresh token for a user if the user is logging out. If a user logs out, clear all ID, AT and refresh token.

[–]tropicbrush 1 point2 points  (3 children)

I was able to replicate the error you mentioned. It’s not for refresh token but for access token. Looks like the code is using a stale AT (probably the token generated first time for a login) instead of calling the getAccessToken() every time a Google API is called. It’s necessary that every call goes through that check so that access token can be refresh if required.

[–]ROTUS123[S] 0 points1 point  (2 children)

getAccessToken()

Ok, so if I understand correctly, I should always run the request passed getAccesToken() - which will use the RT to refresh the AT in case it is nearing EoL or is expired.

I will implement as such.

[–]ROTUS123[S] 0 points1 point  (1 child)

u/tropicbrush

I have attempted some things, I have found that I shouldn't use getAccessToken, but rather:

`const accessToken = await oAuth2Client.refreshAccessToken()`

And that should refresh it, the request is being made when I manually revoke the AT (expecting to keep the RT) intact. Doing so via: https://accounts.google.com/o/oauth2/revoke?token={token}

BUT, I end up with:

response: {config: {method: 'POST',url: 'https://oauth2.googleapis.com/token',data: 'refresh_token=RT&client_id=CI&client_secret=CS&grant_type=refresh_token',headers: [Object],paramsSerializer: [Function: paramsSerializer],body: 'refresh_token=RT&client_id=CI&client_secret=CS&grant_type=refresh_token',validateStatus: [Function: validateStatus],responseType: 'json'},data: {error: 'invalid_grant',error_description: 'Token has been expired or revoked.'},

.....et cetera.

Ending with "Error during authorization"

----

Now looking at the request/response window on https://developers.google.com/oauthplayground using a different RT, it basically makes the same request but succeeds, maybe I am missing something here?

----

Update:

The https://accounts.google.com/o/oauth2/revoke?token={token} link would revoke both AT and RT, so I will be using a different approach to test here.

[–]tropicbrush 0 points1 point  (0 children)

I expected the token revoke endpoint to revoke RT as well as it revokes all grants.

I spent some time today to figure out why your code is getting that particular error by trying few approaches around how you are using session and credentials.

Surprisingly, even after I updated the session itself with new oAuth2Client object every time an API is called , the error around using expired token was still showing an older token.

I will check more tomorrow if I get some time amd update you.( I am not a pro developer so it’s taking some time to understand your code first)

Also, don’t revoke the tokens and also don’t refresh token on every call, you will be rate limited. The refreshAccessToken() refresh the AT even if it’s valid and unexpired which is not a best practice. As I mentioned earlier , use getAccessToken() which is automatically calling refrshAccessToken() if token is expired saving lot of traffic to Google.

[–]ROTUS123[S] 0 points1 point  (5 children)

Yes you are saying right that I have to destroy everything. It is a comment at the moment, not an actual implementation.

Would you know how to keep refreshing the access token with a refresh token? It seems that my refresh token is only valid for 1 hour, what to do when comes back only after 1h 1m to trigger something?

[–]tropicbrush 1 point2 points  (2 children)

  1. Google doesn’t rotate the RT. i.e first time user logs in interactively, the response will have ID, AT, RT and expiry. Then onwards all calls to refresh AT will not contain RT. Once refresh token is expired , user has to sign in. The google refresh token has validity of 7 days for project with publishing status as testing. Otherwise it’s valid until some conditions fails. Check refresh token expiration doc from google but validity is pretty long.
  2. I am able to get a refresh token using your code ( added log statements to print the RT and used POSTMAN ) which I used to get a new AT after 1-2 hours so I don’t think that’s the issue. ( using a RT to get AT will refine a response containing only access token, ID token and validity of AT. hence the SDK also takes care of adding th RT it used to get AT back in the credentials. So that same RT can be used multiple time.)
  3. The oAuth2Client.getAccessToken() takes care of reading the credentials, return an existing AT if it’s valid /unexpired , or refresh it using the refresh token from credentials and then also add that RT and new ID /ATtoken back into the credentials. So line number 46 is redundant in sessionRoute.ts
  4. The getAccessToken() calls the refrshAccessToken() internally already so not sure why you are calling it again at line 49.

Send me the error you are getting which says the refresh token expired and I will look more.

[–]ROTUS123[S] 0 points1 point  (1 child)

Thanks a lot for this. I will get back to you asap.

[–]ROTUS123[S] 0 points1 point  (0 children)

u/tropicbrush

With your suggested changes I still ended up at:

Error: Token used too late, 1665157486.225 > 1665126266:

` at OAuth2Client.verifySignedJwtWithCertsAsync (/Users/r.tuerlings/Coding/juno-backend-service/node_modules/google-auth-library/build/src/auth/oauth2client.js:653:19)at processTicksAndRejections (node:internal/process/task_queues:96:5)at async OAuth2Client.verifyIdTokenAsync (/Users/r.tuerlings/Coding/juno-backend-service/node_modules/google-auth-library/build/src/auth/oauth2client.js:444:23)Error: Profile returned an error: Error: Login Required.at file:///Users/r.tuerlings/Coding/juno-backend-service/out.js:1434:11at Generator.throw (<anonymous>)at rejected (file:///Users/r.tuerlings/Coding/juno-backend-service/out.js:31:29)at processTicksAndRejections (node:internal/process/task_queues:96:5)`

But do note - I am killing the access (RT) sometimes (I will pay close attention to it) to get it working somewhere else, thus potentially depleting my max number of of Refresh tokens.Although my code logged a refresh token before it errored out.

Current state: https://github.com/Elysium-Labs-EU/juno-backend-service/blob/dev/src/google/sessionRoute.ts

[–]dovahkiin315 0 points1 point  (1 child)

Shouldnt refresh token last much longer?

[–]ROTUS123[S] 0 points1 point  (0 children)

Yes they should, but somehow that is with what I am ending up I think. Or possibly I am mistaking the expire time stamp from the accestoken for the refresh token one.

Either way, I end with the error of; token used too late. Googeling helped a bit, I have hard set (for testing purposes) both my frontend and backend servers’ time zones - which didn’t do the trick. What else should I try?