I am able to generate the token and validate it.
Now, I come across a scenario: How can I keep the active user's token refresh everytime it send request to server? Rather than suddenly logout them out after the default token's expiration time.
As per lcobucci suggestion, regenerate the token in every request make by the user. Meaning the Web/MobileApp have to update the new token in local which return from API in each request?
Any other suggestion/approach I should look into?
I am using it for Mobile and Web apps.
Thanks
Related
I've seen this issue in a lot of questions, but so far, none seem to apply to my situation.
The problem we are having is we are getting an "invalid_grant" error when we attempt to get an access token. This only happens to some accounts, but when it does happen, in every case I looked at, the refresh token worked before, and now has stopped working. This is happening far to frequently for it to be customers revoking access (seems to be nearly 20% of the channels we manage in the last couple weeks have been invalidated).
As a note, we have a backend process that uploads the videos to our customer's YouTube channels.
We use OAuth2 to get a refresh token, here are the parameters we send...
scope = "https://www.googleapis.com/auth/youtube",
client_id = "",
response_type = "code",
access_type = "offline",
approval_prompt = "force",
redirect_uri = "http://www.us.com/OAuth/YouTube"
NOTE: for client_id we use the email address that is in the Google API manager (or was, I just looked and it is no longer there). We used to use the client ID from this page, but that caused us problems as well. Did this change? Should we be using the client ID from this page now?
We exchange the code that is returned for a refresh and access token and store the refresh token in our database.
The backend process exchanges the refresh token for an access token and this is where we seem to be getting the "invalid_grant" error.
Guaranteed only a single access token for the channel is in use at any time (25 limit doesn't apply). We don't store the access token, we get a fresh one every time we process a channel.
Any ideas what might be happening? Something to look for? See note above about client ID. This might have something to do with it, but I'm hesitant to try it since using the "Client ID" from the API manager caused problems before.
Guaranteed only a single access token for the channel is in use at any time (25 limit doesn't apply). We don't store the access token, we get a fresh one every time we process a channel.
This statement is incorrect: Access tokens can be used as many times as you need while they are still good (for an hour).
Answer:
"invalid_grant" basically means that your refresh token no longer works. The only solution to the problem is to request access again and get a new one. The question should be why is it expiring in the first place.
Assuming that the user did not revoke access, and that the refresh token has been used to request a new access token within the last six months. This is probably an issue with it being over written.
When a user authenticates your application you are given a refresh token. This refresh token is associated to the client id of your application and the user who has just authenticated. If said user then authenticates your application again you will get another refresh token. Again this refresh token is associated to the user and your projects client id. Both of these refresh tokens will work. Your user can keep doing this up to 25 (Note I think the changed it recently to 50 but I haven't tested it with all APIs yet) once they have hit this magic number the first refresh token will expired and if you try and use it you will get an invalid grant.
The only solution is then to just request authentication again. It is important to always save the most recent refresh token that your user has granted your application. In the event (like me) you have an application that is stored on a number of servers all requiring authentication. Your going to have to tell them not to refresh it to many times or they will have to go back and reauthenticate the first one that they expired.
If this is happening with ALL of your requests. You can also check that you server is sync with (NTP) and that you are sending the payload of your request in the post field. Not attached to the authentication end point like a HTTP GET (been there done that).
Here are the possible reasons why a token stops working and becomes invalid:
The user has revoked access.
The token has not been used for six months.
The user changed passwords and the token contains Gmail scopes.
The user account has exceeded a certain number of token requests.
As you can see, it's not recommended that you request a fresh one every time you process a channel. As also mentioned in Token expiration:
If you need to authorize multiple programs, machines, or devices, one workaround is to limit the number of clients that you authorize per user account to 15 or 20. If you are a Google Apps admin, you can create additional admin users and use them to authorize some of the clients.
With regards to the use of client_ID, it is usually needed to call the sign-in API as mentioned in Creating a Google API Console project and client ID.
And lastly, this Google Groups discussion - OAuth 2.0 400 - error:invalid_grant and ideas? might also help.
Say I'm developing an Evernote or YouTube client, and after the user logs in, the app gets an authorization token from the API server.
Then I use this token to interact with the server until, sometime later, the token expires.
The key is, I don't know if this token is expired until the server returns an error with a message like 'token expired'. Then I have to fetch a new token. Maybe it occurs while the user is posting a message.
So what is an elegant way to deal with this scenario? I want to combine fetching a new token with continuing the last request, so that the user just feels it works as usual.
It depends on which flow you're using. But in general, if you are able to refresh the auth token (via refresh token) without redirecting the user for credentials again, you should do it seamlessly.
Also, you should know exactly when a token is going to expire. If you're coding against an OAuth 2 implementation, the auth token response should give you an 'expires_in' field as a time span telling you exactly how long the token will expire after it was issued to you.
I have developed a rails application that allows a user to login using their google account and then the application fetches the emails and parses them for information.
All this works fine, but I am facing issues with access token become invalid, hence I have been looking into refreshing the token. I found some code at:
https://stackoverflow.com/a/14491560/718087
With this code I have been able to get a new access token that works. But I have a few questions:
How many times can I use the same refresh token I got the first time? or do I need update my refresh token as well, each time I get a new access token? note: application is setup with offline access.
Do I need to refresh the token before it expires or it will still return to me a valid token after the old access token has expired? This will allow me to decide an approach as to when I should refresh the tokens - a: right before fetching the emails, b: automatically before the token expires via delayed jobs or something (this would add quite a overhead though)
I have gone through the api docs but could not find answer to my these specific questions. Please excuse my overly detailed queries.
Thanks,
Aditya
Refresh tokens never expire, unless revoked by the user. You should store it safely and permanently. You should definitely not go back and get new refresh tokens over and over, because only a certain number can be understanding per user/app combination, and eventually the older ones will stop working.
In answer to your question: "Do I need to refresh the token before it expires or it will still return to me a valid token after the old access token has expired?"
I have a rails app, and I check for expiration & refresh token existence:
if client.authorization.expired? && client.authorization.refresh_token
#then I refresh here...
So the answer is, Yes you can (and probably should) wait until your access token expires, and then refresh it.
I'm writing a Google calendar app in rails. The OAuth2 access token expires after 1 hr. My problem is, if someone fills out a form that I want to push to Google calendar, and while they are filling out the form the access token expires and they have to go thru the whole re-authentication process, I don't know how to preserve the entire request (form submission) and resubmit it, once my token is refreshed.
I know it's possible using a DB, saving the params, the path, the request method, and all that... but what I want to do is save everything in a session variable of some sort, and have it automatically re-submit the whole request to my app again, once the Google OAuth access token is valid.
Any ideas?
This is solvable by getting a refresh_token with which you can get a new access_token. You can do that by asking for offline access when the user first authorizes your app.
You can also use the Ruby client library that Google provides to manage the OAuth2 process easier for you.
You can also save the form state in the current session, assuming you have one, then do an immediate flow just to grab a new access token. See the prompt=none parameter:
https://developers.google.com/accounts/docs/OAuth2Login#authenticationuriparameters
The immediate flow will succeed only if the user has a valid session with Google. If that's not the case then you do have to send the user to re-authenticate in the normal flow.
Or, as Arun suggested, use a refresh token. But with a refresh token you definitely have to run you own session and keep a user database (you have to store the refresh token). Your own session may also expire before the form is submitted.
I need to download my Delicious bookmarks to a non-web application without constant user interaction. I'm using Delicious's V2 API (using oAuth) but the problem is it seems their access tokens expire after one hour.
I don't have any issues with redirecting the user to Yahoo for a one time authorization, but what is described here (http://developer.yahoo.com/oauth/guide/oauth-refreshaccesstoken.html) means I would have to refresh my access tokens all the time before they expire when the user is away.
Is this really the way they've done their oAuth implementation?
You only need to refresh the access token when they come to use the application again, not while they're away. You can pass the previously expired token and get a new one in return.
Is that a problem? You should only need to make an additional server-side call to refresh the access token if it expires (as long as the authorization itself has not expired, which should last longer, and would need user interaction when it expired).