I've been working with the Google API. Sometimes my refresh token refreshes and other times it fails and causes a 'RefreshError.' Why? How to fix? - python-3.x

Error:
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})
However, another app I use, with a different account, never runs into any issues. I use the same Python OAuth Quickstart for both.

Token has been expired or revoked.
Basically means just that either the user has revoked your access or google has. Users can remove your access directly in their google account when ever they want to.
Google expired tokens
If you are using a gmail scope, and the user changes their password. Your refresh token will probably be revoked.
If your app is still in testing and the refresh token is more then seven days old the users consent will be removed and the refresh tokens will be revoked.
If the refresh token has not been used in more then six months the refresh token will be revoked.
If the user authroizes you app you get a refresh token, if the do it again you get another refresh token. both will work. You can have up to 50 outstanding refresh tokens for a user. If you request again then the first one will be expired. Ensure you are always storing the most recent refresh token.
no matter what the cause your application should be configured in a way as to request authorization from them again if the refresh token has expired.

Related

how to do authorization (nodejs, express) with two tokens (access/refresh)

Good evening, I ran into a problem that I need to make authorization more secure and without re-logging. I read on the Internet that you need to use two tokens (access and refresh), but how to properly do authorization with them. You can advise a resource where competent authorization with two tokens is made.
My Tech Stack:
MongoDB
ExpressJS
ReactJS
NodeJS
If you request authentication with offline_access scope, you'll geta refresh token in addition to an access token. Save this refresh token to the database and whenever you need to make another call on behalf of the user you can
Make the call using your existing access token. If you don't get a 401, then you're good.
If you did get a 401, your token is probably expired and then you can call the token end point on the authorization server with the refresh token and grant_type=refresh_token to get a new access token and try your call again.
Might make the most sense to always request a new access token using your refresh token before you make another call.
To my knowledge you only deal with access tokens for authorization. The refresh token is only there to refresh an expired access token. The refresh token is exchanged for a new access token - without needing to present authentication credentials again. The call also (typically) takes a fraction of the time than re-authenticating.
as soon as the user log-in, give it two tokens refresh and access, store the refresh token in the database, give access token a expire time (5-10 min approx or less depending on your requirement).
for each request user will use the access token and for each request backend should check for the expired access token.
if the access token is expired, user will get a new access token by sending the stored refresh token to the backend(using a dedicated endpoint), backend will than check whether the refresh token is present in the database or not, if yes a new access token with new expire time will be sent in the response.
the cycle will continue until the user logs-out, in that case the refresh token will be deleted from the database and after some time access token will also get expire.

Access Token and Refresh Token flow

I have read about JWT and access token and refresh token. I understand that you have to set access token expiration in a very short time (minutes) and use refresh tokens to obtain a new access token whenever is expired.
Three things are not clear to me:
Who checks access token for expiration? Is client checking that and requesting a new access code by sending expired access token along with refresh?
Who checks refresh token for expiration? (obviously refresh token needs expiration as well although it takes longer to expire).
From my point of view if a refresh token is expired, the user must be prompted to re-login. This is something that needs to be avoided in some scenarios (mobile apps). How can it be avoided?
Answer your question:
The API use access token will return error when access token expired.
The API use refresh token to get a new access token will return specific refresh token related error.
About refreshing of the refresh token, please see the below answer.
Generally you need do some error handing for each API calling.
About refreshing of the refresh token
I investigate more, and this is what I found:
first time login and authorized to get access token and refresh token(optional), if access token never expire refresh token is not necessary. => https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/, recently(2019/11/16), I found this really depend on the implementation of the API providers, for example, PayPal, They provide access token with expired time but without refresh token, so when the access token expired, you have to get a new access token again.
when access token expired, use the refresh token to get a new access token and refresh token(optional) => https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/. this time you have a new refresh token, which means you have a new refresh token every time you refresh a access token. if the response don't have a new fresh token, you only have the old refresh token from the first step.
If user don't use the app for a long time, then user don't have chance to refresh the access token and refresh token, then user need to re login again after long time when refresh token expired.
like #jwilleke said, even user do not use the apps, the server side or the apps can do it for the user automatically, then it will always have the new access token and refresh token.

How long is the refresh token valid?

On my localhost, I have authenticated my user and goten a Refresh Token and Access Token using Passportjs.
I am using Google's Official Node.js library to get the Google Analytics data and it all seems to work fine.
On this GitHub issue, Justin clearly mentions that the expiry is set by Google's APIs.
How long is the refresh_token valid and at what time do i have to authorize myself again?
This is more of an Oauth2 question then a Google Analytics question.
Access tokens on google servers are good for one hour.
The refresh token does not expire and you can use it as many times as you want to request a new access token.
You should still handle invalid refresh tokens in your code. The user can revoke your access via there Google account. You can have max 50 out standing refresh tokens before the first one starts working. If i authenticate your application you will be given a refresh token if i do it again you get another refresh token there can be max 50 of them outstanding.
If the refresh token does become invalid you should just request authentication from your user again. The library you are using should be handling refreshing the access token for you.

Azure AAD token expire issue with web app

We are using Azure AD authentication with a bootstrap MVC site.
Everything is fine and dandy - except we have an issue with the token timeout.
I have read multiple articles about the token lasting 1 hour before re-authenticating against Microsoft.
Our problem comes up when posting data.
Efter we enter a page with a post form on it - and this hours expires when on the page - the post data gets lost when posting the data. Everything points in the direction of the problem occurring when the site goes to get a fresh 1-hour token.
Has anyone here had experience with this or have any idea of how to get around this problem?
Not sure if this is the right way of doing things, but this is how we're handling this situation.
Basically when a user authenticates against Azure AD, you get 3 things back - Access Token (which expires after 60 minutes), Refresh Token and Token Expiry. What we do in our application is cache these three items.
Whenever we perform something that requires Access Token, we first check if the token has expired or not (by comparing the server date/time with the token expiry). If the token is not expired, we simply use that access token. However if the token is expired, we fetch new tokens using refresh token (fetching new tokens using refresh token will again return Access Token, Refresh Token and Token Expiry which we cache again in our application).

How to get a new Google oauth access token from refresh token in passportjs

there seems to be some conflicting advice on how to get an access token from a refresh token:
This SO answer says passportjs doesn't get involved with refreshing the access token and it should be done via cron job:
Refresh token in Passport.js
This SO answer says "No need for any cron jobs...when the user requests data from the API using an access token that has expired, this should trigger your framework to fail, renew, then retry."
OAuth 2.0 - When should an access token be renewed with refresh token?
What's the simplest way to ensure we're always giving Google a valid access token? Right now, we're just storing the refresh token in the database and never using it, which forces users through the "allow / deny permissions" flow every time their access token expires.
There are a few approaches. One is to just detect when the access token fails (with 401 I believe) and then refresh it and re-use it. However, most of the APIs that yield access tokens also tell you their expiry time, so you can just remember that and, when you’re about to use, if it’s less than say 10 min before expiry time, refresh then. If all else fails you could use the tokeninfo endpoint when you get a new access token, to find out its lifetime.

Resources