I want to use Google API refresh tokens forever - google-api

There is a process to obtain a refresh token via OAuth authentication for Google API, and then obtain an access token from the refresh token to validate the receipt.
The other day the refresh token suddenly expired and the receipt validation failed. Our service stopped processing billing.
Below is the error when it failed.
{
"error": "invalid_grant",
"error_description": "Token has been expired or revoked."
}
I thought refresh tokens reset their expiration date each time they are used, so why did they expire?
I don't think the following rules apply.
You must write your code to anticipate the possibility that a granted refresh token might no longer work. these reasons:
The user has revoked your app's access.
The refresh token has not been used for six months.
The user changed passwords and the refresh token contains Gmail scopes.
The user account has exceeded a maximum number of granted (live) refresh tokens.
The user belongs to a Google Cloud Platform organization that has session control policies in effect.
(https://developers.google.com/identity/protocols/oauth2)
I want to use the refresh token forever.
Thank you in advance.

Refresh tokens do not expire by design there are a few things that can cause them to expire as you have listed. However there is one you have not listed.
If you check the docs for Experation you will find it also says.
If your app is in testing set it to production and your refresh token will stop expiring.
So as long as your app is in production, the user does not revoke your access, and they have less then 50 outstanding refresh tokens for that user, and you have used it at least once in the last six months. (gmail scope the user does not change their password). The refresh token should not be expiring.
That being said your system should be designed to handle a refresh token expiring and request access of the user again. or notifying the admin if this is a backend system.

Thank you for this interesting conversation. It looks like in my case, after having got an access_token and a refresh_token, which I use regulary to invoke the Gmail API, it no longer works after 6 months.
Could someone point me to a code example in Node, showing how to update the tokens on a regular basis? (I store them in a database, and wonder how to update the record appropriately via the google.auth.OAuth2 API).
I have made hundreds of searches but could not find anything else than "you should refresh your tokens" :)
It looks like
oauth2Client.on('tokens', (tokens) => {
logger.info("tokens=%o", tokens)
})
is only invoked once when establishing the connection, so it will not help.
I have also tried:
let x = await oauth2Client.refreshToken(database_refresh_token)
let refreshedToken = x.tokens.access_token
To store the new refreshed token in the database, but this does not help after 6 months. FYI, thanks to oauth2Client.getTokenInfo(refreshedToken) I can see that refreshedToken expires in 1 hour.
Finally, is there a way to test, without having to wait for 6 months?
Many thanks!

By last answer...
It means we can used one refresh token for 6 month. right ?
And after 6 month we have to update refresh token. right ?

Related

How to set expiration date in Google OAuth 2.0 Client IDs , in google developer console portal

I am setting up my Google Oauth 2.0 client credentials but it is getting expired in 2-3 weeks. Can anyone tell from we can set expiration date of credentials in google developer console portal.
Credentials are for desktop app.
I have tried exploring all the details in google console but can not find option of setting up expiration date.
The primary thing with Oauth that makes it secure is the fact that tokens expire.
An access token for example will expire after an hour so if anyone gets it they can only cause damage for a limited amount of time.
Refresh tokens can be used to request a new access token when the access token expires.
Refresh tokens can expire for a number of reasons
Your app is in the testing phase and there for the refresh token will expire after an hour.
your using a gmail scope and the user changes their password.
The user authorizes your application once you get a refresh token, they authorize it again and you get a second refresh token. This can continue with up to 50 outstanding refresh tokens after that the first one will expire. Always remember to store the latest refresh token.
There is no way to extend the life of any of the tokens this is configured by google in their authorization server.

my app is not able to receive refresh token from Google anymore

i have a very weird problem. I'm using the Google authentication API since moree than one month now and all working perfect. But now out of the sudden, my users can't get refresh token anymore. My app is on testing state, so i thought the refreesh token my testing user was having is expired after 7 days, but then i tried to get another refresh token by doing thee authorization from the beginning to receive a code that i use to get a refresh tokn. But no chance i'm only receiving this response back: Status code 400 { "error": "invalid_grant", "error_description": "Bad Request" }
Thank you very much for your help!
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.
To stop your refresh tokens from expiring set it to production.
Why cant you refresh after seven days
What i am writing here is my opinion only from experience. There is no documented proof of any of this from googles side.
After seven days your refresh token will expire, but the question is how is google expiring these refresh tokens. From what i can see they are not using the normal method of expiring the refresh token. They are in fact revoking the users granted access on the google account. So the all of the refresh tokens granted will stop working at once.
So why are you having issues with the client library. Normally the way the client libraries were originally designed. if the refresh token expired it would prompt the user to authorize the app again. This does not happen with the seven day revoke method. IMO because the error message is different, and the libraries have not been updated to take this into account, and prompt for access again. The only way to fix it is to delete the old stored refresh token and request a new one.
So your not able to receive new refresh tokens because your code is stuck with the old one. Make sure to hard delete any old refresh tokens you have stored. They wont work and the library doesnt understand how to delete them on its own.

Server-to-server Facebook Access Token expires

I am building an Integration that allows users to schedule creation of Custom Audiences on the Facebook Ads platform. Once the user authenticates, we pass the client side token to the server from the client and then exchange their short lived token with the ads_management permission for a long-lived token, but that token only lasts 60 days?
The idea of the integration is that the user can set it and forget it (but disconnect any time). Now it seems like they need to visit the app at least once every 60 days. Is there any way around this? In my app, the person who turns on the Integration might not necessarily visit the app, or could leave the company and the integration would then break in 60 days.
You can simply ask Facebook for a new access token by passing your current access token.
It's as easy as exchanging the long-lived token, just re-call the same operation (using the current long-lived token). You will get a new one.
I suggest doing so some days before it expires (say, 10 days). This will ensure your system is going to have a spare time if any error occurs (e.g. Facebook's server down, User rejected permissions on your app, ...).
Just like Michael Hirschler said in his answer, you can simply use the old (non-expired) access token to fetch a new one. You should save the expiry date returned on every request when getting an access token: (This property is called expires_in)
{
"access_token":"{long-lived-user-access-token}",
"token_type": "bearer",
"expires_in": 5183944 //The number of seconds until the token expires
}
When expiration date is almost reached, you can use the same api endpoint for that with some changed query params. Insert your old access token as the user-access-token.
curl -i -X GET "https://graph.facebook.com/{graph-api-version}/oauth/access_token?
grant_type=fb_exchange_token
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={user-access-token}"
As you can see, you will also need your app-id and app-secret for doing so.
Further reading: https://developers.facebook.com/docs/facebook-login/access-tokens/refreshing/

Django REST JWT Refresh

Implemented Django REST and authentication using JWT.
For JWT token we have to refresh it before it expire.
After expired JWT wont give new token.
For my mobile device I need to refresh the token every 10 mins (JWT_EXPIRATION_DELTA).
and if user is not active for more than 10 minutes, then I need to ask to login.
Is there any way that I can refresh the token even after JWT token expired. (we can limit the time to refresh as 2 day)
Whats the best way to handle this behavior in Mobile.
Thanks.
Refreshing tokens in django-rest-framework-jwt
The django-rest-framework-jwt (v. 1.11.0) does not support "Refresh Tokens" as described for example here. It only supports refreshing non-expired tokens; It makes easy to implement a sliding expiration window with width of JWT_EXPIRATION_DELTA. For example, with settings
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
user cannot be inactive for more than five minutes in order to stay logged in (docs).
Real Refresh Tokens, please?
It is possible to implement the "Refresh Tokens", which are very long lived ("never expiring") tokens, stored in a database, just like in conventional "HTTP Sessions & SessionIDs". This is actually already been implemented for the django-rest-framework-jwt in django-rest-framework-jwt-refresh-token. Another possibility is to use django-rest-framework-simplejwt which also implements the JWT with Access and Refresh Tokens (full example at Medium).
But.. why?
Compared to using only Access Token JWT's, using Refresh Tokens makes possible to revoke access after the Access Token is expired. Refesh Tokens make it possible to have very long ("lifetime of a mobile device") lasting tokens. One may ask why shouldn't you just stick with sessions (sessionid in a Cookie, and session data in database table), if you are creating collection of Refresh Tokens in a database, and accessing that. Using an Access token with expiration time of one hour will mean that database must be accessed once per hour (instead once per PUT/POST request when using "traditional" sessions). In addition, you gain all the usual benefits of JWT tokens (ease of use in microservice network, for example).
You can use refresh tokens, as defined in Oauth2.0
Refresh tokens are credentials used to obtain access tokens. Refresh
tokens are issued to the client by the authorization server and are
used to obtain a new access token when the current access token
becomes invalid or expires,
After a successful login, issue a refresh and an access token. While a access token expires shortly, a refresh token is long lived. Store it securely, and use it to issue new access tokens when the current one expires

VSTS API Refresh Token Expires

I'm using the VSTS REST API. I use the refresh token, as instructed, to refresh the access token. This morning, the refresh tokens stopped working. Do they expire? If the access token and refresh token have both expired, how do I proceed? I can't find anything on this.
For reference: https://www.visualstudio.com/en-us/docs/integrate/get-started/auth/oauth#refresh-an-expired-access-token
Yes, the refresh token will be expired, you need to send request to re-authorize to get access token and refresh token again (your previous steps to authorize).
The previous access token and refresh token have been expired after get new access token.
I manage the team that implements this flow. The answer from #starain is correct and this flow is described in detail in the OAuth 2 specification. Your observation that the refresh token is invalidated so frequently #scottndecker is not consistent with the implementation. A refresh token in our system has a default lifetime of one year. The token can also be invalidated manually by users. We obviously must honor the user's right to revoke a previously granted authorization. If you want to share some more information we can certainly look into this behavior.
Seems that when the auth.token expires (after one hour), the auth.refreshtoken become invalid too? What is the auth.refreshtoken purpose then? When I decode the auth.refreshtoken on jwt.io, it should expire sometime in 2020. (Now it's 2019).
While the auth.token is valid, I can refresh and get a new token. So is the idea that I should setup a job that refreshes the token within one hour?
The documentation claims:
If a user's access token expires, you can use the refresh token acquired in the authorization flow to get a new access token. This process is similar to the original process for exchanging the authorization code for an access token and refresh token.

Resources