error: invalid_grant , for getting access token using refresh token - google-cloud-platform

After googling we came to know that invalid_grant which means refresh token is invalid.
Link to google oauth doc
We don't have any of these issues mentioned by google. Is this error related to something else rather than a refresh token.
More Info
We have access to read, write spreadsheet and send gmail
We fetch an access token for each request
Any help would be appreciated.
We're already in production and verified by google

Without seeing the full error message that being
Invalid_grant {Message here}
It is hard to help but from my experience is most often caused by one of the following.
Refresh token expire, app not in production.
There are serval reasons why a refresh token can expire the most common one currently is as follows.
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.
The fix is to go to google developer console on the consent screen and set your application to production, then your refresh token will stop expiring.
invalid_grant: Invalid JWT
{ “error”: “invalid_grant”, “error_description”: “Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values and use a clock with skew to account for clock differences between systems.” }
Your server’s clock is not in sync with NTP. (Solution: check the server time if its incorrect fix it. )
invalid_grant: Code was already redeemed
Means that you are taking an authentication code that has already been used and trying to get another access token / refresh token for it. Authentication code can only be used once and they do expire so they need to be used quickly.
Invalid_grant: bad request
Normally means that the client id and secrete you are using to refresh the access token. Was not the one that was use to create the refresh token you are using.
Always store most recent refresh token.
Remember to always store the most recent refresh token. You can only have 50 out standing refresh tokens for a single user and the oldest one will expire. Depending upon the language you are using a new refresh token may be returned to you upon a refresh of the access token. Also if you request consent of the user more then once you will get a different refresh token.
User revoked access
If the user revoked your access in their google account, your refresh token will no longer work.
user changed password with gmail scope.
If your refresh token was created with a gmail scope and the user changed their password. your refresh token will be expired.
Links
Oauth2 Rfc docs for invalid_grant error rfc6749
invalid_grant
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.

Related

Revoking 1 token revokes all tokens of same OAuth Client ID + User Consent Pair

I'm experiencing a situation where:
I have a Google project, using an OAuth 2.0 Client (for web applications), to get consent for some scopes from users. The authorization parameters used in the redirect to Google uses the following values for the parameters (only including the possibly relevant params):
access_type - offline
response_type - code
include_granted_scopes - true
If a user consents access to the app, the app gets an access token to access the scopes granted.
If the same user consents again (while the previous access token hasn't been revoked yet) to the same app (using the same OAuth 2.0 Client), a new access token gets issued to the project.
The Google project has 2 different tokens now, and both access tokens work for accessing the scopes granted. Oddly though, the user would see only a single entry for the Google project/app in the users Apps with access to your account page.
The issue is that if any of the token gets revoked, all of the active tokens get revoked (attempts to use the access token results in an invalid_grant error, with the Token has been expired or revoked. error description). While I haven't tested beyond having 2 live/valid tokens at the same time, I suspect the behavior would be the same for more than 2.
I've been looking through the Google OAuth 2.0 docs to find some documentation regarding this behavior, or find anything referencing what happens to companion tokens when one gets revoked, but was unable to find anything explaining this behavior.
I, at first, thought that it was maybe due to my usage of incremental authorization, and thought that maybe revoking the latest access token revokes all preceding ones, but after experimenting with include_granted_scopes=false, the behavior was still the same.
For now, I've restricted users to be able to consent only once (unless a token expires), but I'm curious about the explanation for this behavior - where revoking 1 token revokes all of them.
Actually access tokens are independent. An access token by design will work for one hour. In theory even if the user revokes your access the access token will still work for the remainder of the hour it was originally valid for. This is standard Oauth2 functionality they are intended to give access for an hour that is why it is called a bearer token the bearer of that token is granted access for an hour.
What i suspect that you are seeing is the refresh token being revoked as this will cause a invalid_grant error. If you request access of the user using offline access you are granted a refresh token. If you request consent of the user again you get another refresh token. There can be up to fifty outstanding refresh tokens for a single user.
If the user revokes the access via their google account, or if your application revokes the access. Then yes all of the outstanding refresh tokens will be revoked. As your applications access to the users account has been revoked not the single refresh token. Note there are actually serval reasons why a refresh token can expire they can be found here refresh token experation
This is standard Oauth2 behavior not google specific.
Remove third-party account access
If you gave Google Account access to a third-party app or service you no longer trust or want to use, you can remove its access to your Google Account. The app or service won’t be able to access any more info from your Google Account, but you may need to request that they delete the data they already have.

why oauth 2.0 client id expired automatically?

Execute compute engine
api(GET https://compute.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instances/{resourceId}) with oauth 2.0 client id.
I created an OAuth2.0 client ID and got access_token and refresh_token based on the steps on this site.
Obtaining OAuth 2.0 access tokens
Refreshing an access token (offline access)
I can execute api with access_token which was refreshed.
after 3days, run this step again,
https://developers.google.com/identity/protocols/oauth2/web-server#offline
response was
json
{ "error": "invalid_grant", "error_description": "Token has been expired or revoked." }
why expired refresh_token?
refresh_token
A token that you can use to obtain a new access token. Refresh tokens are valid until the user revokes access. Again, this field is only present in this response if you set the access_type parameter to offline in the initial request to Google's authorization server.
There are a lot of things which can cause a refresh token to expire.
you are using a gmail scope and the user changed their password.
it has not been used in six months.
the user has revoked your access in their google account.
If the user runs your app you get a refresh token, if they run it again you get a different refresh token, you can do this up to 50 times and get new refresh tokens and they will all work after number 50 the first one will expire. Make sure you are always saving the most resent refresh token.
your app is currently in testing and has not been set to published and has not been though the verification process.
Documentation link for expiration

Automating cf login refresh

Does the CloudFoundry UAA support token refresh for logged in user.
I'm currently logged in using the "cf-cli" via the SSO passcode. After a week or so the session expires and I have to log in again.
Is it possible to refresh the token in the $HOME/.cf/config.json upon expiry ?
As per this https://www.rfc-editor.org/rfc/rfc6749#section-6 , we should be able to refresh the token by passing
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA options.
However, it expects the client_id or client_secret to be present i.e use BASIC Auth.
Can we do with a currently logged in user ?
You can refresh an access token, but you cannot refresh a refresh token. When your refresh token expires, you must login again.
The refresh_token from config.json is a JWT token, so you can use a tool like https://jwt.io to view the token and see when it expires. Your refresh token will expire at some point, it just depends on how long your administrator allows it to last. A week sounds pretty standard.
Hope that helps!

MSGraph invalid refresh token due to inactivity

We are integrating on our application the Office 365 functionality throught MSGraph rest api and we are currently getting trouble with the validation of Refresh Tokens, this is the response error code from the server on a invalid petition:
"error":"invalid_grant","error_description":"AADSTS70002: Error
validating credentials. AADSTS70008: The refresh token has expired
due to inactivity.??The token was issued on
2016-04-27T11:44:49.4826901Z and was inactive for 14.00:00:00.
This is annoying because we need the users to aquire their credentials again logging in on Microsoft servers.
Is there any option to avoid Refresh token being invalidated due to inactivity? Or to make longer this expiration?
Refresh tokens have a finite lifetime. If a new token (and refresh token) isn't requested before that time they will expire. Once this happens the user must re-authenticate.
If you need to have perpetual access to the account, you will need to manually refresh the token periodically. You may want to look at this article. It covers the basics of how v2 Endpoint works (and the various token lifetimes).
In most of my implementations I use a queue to handling refreshing tokens. I queue each token to be refreshed at 10 days. If it fails I resubmit to the queue. If it is still failing at day 12 I email the user to inform them there was an issue and they will need to re-authenticate.
UPDATE
Refresh token lifetime was recently changed to until-revoked. You can read about the change here
This is general OAuth (not AAD-specific): obtaining an access token is a 2-step process. The first step is to obtain an auth code which requires the user to authenticate. The second step is to redeem an access token and a refresh token from the auth code. This second step is purely programmatic, i.e. the user need not be present. The app can keep repeating the second step, i.e. redeeming a new access token and a new refresh token from the latest refresh token without the user even know about it.
Your app should schedule frequent 'refreshes' of the refresh token. You can do this at any time while the app is running.
If the user doesn't use the app for an extended period of time, like about 2 weeks (I believe), the refresh token would naturally expire. If you want to avoid that, you'll have to schedule a dedicated job to refresh the token.
Zlatko

Firebase php-jwt Token Refresh

I'm using the php-jwt package for my Restful API to authneticate users.
I am successfully authenticating Users and returning a token. However it seems that there is not a standard method to issue a refresh token. Although I understand the principle and the flow I'm not sure if there is a standard for the issuing of the refresh token?
If I unerstand correctly the flow is as follows:
App requests access
API checks for a valid User and issues a token which is to include a refresh token
refresh token is sent along with a request to renew, it is verified and if valid another token is issued?
But my question is how to issue the initial refesh token. Is this simply encoded in the token itself along with other data that I return such as username and email for example?
Thanks in advance. A.
I'm currently doing a bit of research of my own on JWTs. I believe you can give the client 2 tokens after auth: an access token and a refresh token. The refresh token can also be a JWT itself. What goes in it is up to you but I think what's important is that it is a valid/not expired token when used. If you can successfully validate it, then you can issue a new access token.