All accesses (a dozen) stopped working returning the error "invalid_grant".
I have revoked the application access for one of the user, got a new one, and this access is now working again with a new refresh token.
I wonder what might have happened? I doubt all users changed their password (I read that this can revoked access) and refresh tokens don't have an expire limite.
Everything was working fine until now.
Refresh tokens should not expire if a user changes there password. That is kind of the point with a refresh token.
Refresh tokens can expire if
the refresh token hasn't been used for six months to get a new access token.
if the user in question revokes access via their Google Account.
To many refresh tokens. When a user authenticate your application you get a refresh token associated with your project and said user. If the user authenticates your application again you get another refresh token both will work. You can keep doing this until you reach the magic number of 25 at which time the first refresh token will automatically expire.
Number three could be your problem if you are not ensuring that you are always saving the most resent refresh token. Or if your users have multiple versions of your application running.
If you are having an issues with all of your users I think the problem could be that, Invalid grant can also be the result of Your server’s clock is not in sync with NTP.
Related
Current situation
We have a very common system architecture with Spring Boot back-end and Angular front-end. For the mobile app we use Ionic, which basically uses same codebase as the front-end but adds additional features like biometrics etc.
User login is based on OAuth and access and refresh tokens are created once the user initiates the session. The access token has a short life span, where the refresh token is valid for a couple of days. As I said - very common auth flow.
What we want to achieve
Mobile app users should be able to login only once and then use the
app without the need to re-login every time the refresh token
expires.
For the "normal" front-end app refresh token expiration
policy should stay unchanged, meaning the user is forced to log in
again once the refresh token expires.
Possible solutions (from my perspective)
we pass an additional param to the login request specifying the client: web | mobile. If client is mobile refresh token validity is extended to expire in 1-2 years. Downside: this will break the whole idea of having tokens, that expire. I personally see this as a security issue.
we store credentials on mobile app local storage. Once we have session expiration, the app uses the credentials to re-authenticate. Downside: again I don't think this is a good idea having credentials stored on any device makes the flow vulnerable.
What I am looking for is kind of a best practice to solve this.
You are right, It's a security risk to have tokens that never expire or expire in a few years but they are used. Anyway, one thing you could do is to add a field in the refresh token endpoint that when you set it to true (defaults to false) it would also extend the lifespan of the refresh token. And you could periodically call that endpoint from your app. It should work even when It's in the background.
Or
If you wanna store the credentials in the local storage at least store them encrypted. You might need to create an endpoint that encrypts them because you should not have the private key in the mobile app. Then you'll probably need to create a custom authentication method that takes the encrypted credentials and compares them with the ones in the database.
I've been using the Google API to update one of my Chrome plugins on a weekly basis. This has now happened 3 or 4 times now: The refresh token I acquire will work properly for up to two weeks (only being used once per week), then the third week, returning an error saying that my token has been expired or revoked.
Given that I'm the only user with access to these tokens, I know that there isn't any spamming, and I know that nobody would be authorized to revoke the tokens on my end.
Please advise. Thanks!
There are serval reasons why an access token can expire.
the user revoked your access.
depending upon which scope you are using if the user changes their password it can revoke all out standing refresh tokens (mostly gmail I think)
If your application is still in testing phase refresh tokens only last for two weeks you will need to move your application to production and go though the verification process. (this appears to have been a stealth change i can find no information on it)
you can have a max of 50 outstanding refresh tokens for a users account, if the user is logging in multiple times and you get a new refresh token each time make sure you are always using the newest.
Your application should always be set to request access of the user again in the event that the refresh token has expired.
I have recently worked with Google Ads API and Shopping Content API and experienced detailed behaviour of API authentication mechanics.
What i can tell for sure regarding authentication is the the following:
An Access-Token always have a life time of 60min. and then expires
An refresh-Token makes it easier to obtain a new Access-Token, since
no additional verification is needed
The lifetime of a Refresh-Token varies
it can be a 6 month or more (when the related application publishing status is released)
or just 1 week (when the related application publishing status is testing)
You can find detailed information regarding Token Expiration on the Google API Documentation https://developers.google.com/identity/protocols/oauth2#expiration
Also information regarding publishing status of your API application Token has expired or revoked - Google Ads
I am using this googleapis nodejs client for calendar, and everything works perfect except that if I remove access from google account security settings,
calendar is still connected. Is there any method to check for removed access from google account? How to handle those cases?
When a user runs your application the first time they are presented with a consent form. Which asks them to grant permission for your application to access their Google calendar data. From this point on when ever your application runs the user may have to login again but they will not have to grant your application permission. If you have a refresh token you will be able to use that when ever you like to request a new access token. the access token will be valid for one hour.
Now if you request a new access Token as stated its valid for one hour. This is true even if the user goes to Google Account security for their account and removes the consent for an application access their data.
Your still going to be able to access their data while any access tokens you have currently are valid. If the user tries to use your application again they will have to consent permission. If you try to use the refresh token it will no longer work.
Access tokens work for one hour they are not reauthorized during that time its assumed that they are valid. (This may in fact depend upon the scope and API in question and how googles policy server works.)
access token are designed to be self contained permission systems. As long as you have an access token for the correct scope most apis assume that you have access. However in the event this method is accessing critical data then they may have a policy server setup. This server could be doing an extra check on an access token to ensure that the user still has access even though they have a valid access token. However doing this can be very time consuming and resource heavy as reevaluating every call to ensure that the user still has access. It kind of defeats the purpose of having access tokens that are valid for an hour in the first place.
I am using gapi.auth2.authorize to authorize people in my Google Photos API app but I cannont find a why to unauthorize or disconnect them from the app. What I have noticed though is that there is no way of using an old access token so that the user doesn't need to authorize.
How can I make the access token invalid?
Is it correct that every time the API is used the user has to authorize?
Thanks
How can I make the access token invalid?
Not possible to invalidate an access token, it will expire after 1h
You can check documenttation here
Is it correct that every time the API is used the user has to authorize?
Nope, you should ask users to authorize only once, using a refresh token that you can keep in your back-end, thus allowing your app to content on on users behalf all the time, until they revoke permissions
Is there a way to change the validity period of a refresh token within Windows Azure Access Control Service. Based on the following article, refresh tokens last a year but I cannot find a way to change that, either on the portal or via the management service. I am aware of the token time out when crating a relying party application but this, as I understand it, refers to the time out of the access token not the refresh token.
Any help would be greatly appreciated.
Many Thanks,
User1426145
With OAuth 2.0, the refresh token has expiration time sent along with it and as you described in case of above the limit is about ONE year. You can not change the refresh token validity period once it is issued so you have two option to maintain it alive. Trying to keep track of its validity or when you hit INVALID_TOKEN error, you can to call the same refresh token service to receive a brand new refresh token again.