According to this wonderful and very specific document: the user must be logged in and you must posses a legal access token for this user in order to achieve a successful refresh \ duration extension of the token.
To validate the token and to ask for a full authentication is the easy part, but how do I determine if the user is logged in or not?.
Moreover, what would be the correct implementation here, my original though was to refresh the token, save it onto the DB, and then to cause a full refresh of the page, this way I will not have to find myself in the state of being authenticated with an old invalid token and finding ways to replace it dynamically(of course in order to validate the old token I also need to use it).
Another approach might be to make the a request to a 3rd page that will handle the token renewal after the main page has been loaded, which is what I will try to do.
Related
I know an access token is self-contained and therefore can't be revoked.
To my understanding, this is why the expiration time of an access token often is low. This enables one to revoke the refresh token, and thereby only allow users to be signed in, for the expiration time of the access token.
However, if I understand it correctly, a user is able to renew his token infinitely without the use of the refresh token.
One can initiate a silent authentication request by adding prompt=none. This is possible as long as your access token is still valid. Doing so will return a new access token, that is indistinguishable from a login performed directly without the prompt=none parameter.
If I understand this correctly, a user who once got a valid token is able to constantly renew this without me being able to "revoke" his access in any way?
Am I understanding this correctly, and if so, how do I go about revoking a user's access until he manually signs in again?
The prompt=none silent renewal actually uses the user's IDP authentication cookie and not their access token.
The good news is that ASP.Net Core allows you to store the data held in said cookie on the serverside (e.g. in a database or distributed cache) and thus you can revoke said cookie any time you like. By deleting the cookie data related to that user account you effectively invalidate their current session(s) and thus can prevent any future silent renewals. Likewise you can delete all persisted grants (reference tokens and refresh tokens).
Check out the Microsoft.AspNetCore.Authentication.Cookies.ITicketStore interface and the CookieAuthenticationOptions.SessionStore property.
I'm implementing OAuth 2.0 in my API. We're using JWTs for authentication, and refresh tokens for client-only reauthorization. Should I ask the client to also provide the userId in the body of POST /token so that they're required to know the user and the refresh token together (so you can't just try a bunch of random strings and see what works)? What's the standard?
Guessing a refresh token should not be possible if the spec is implemented correctly; https://www.rfc-editor.org/rfc/rfc6749#section-10.4 says:
The authorization server MUST ensure that refresh tokens cannot be
generated, modified, or guessed to produce valid refresh tokens by
unauthorized parties.
You must make sure that you generate refresh tokens with enough entropy so that the randomness of your refresh token would not become any different by adding the userid to it. Or to put it yet differently: guessing your refresh token would be just as hard as guessing userid+refresh token. Besides that, adding a user id in the POST would make it actually more predictable than adding a random string to the refresh token with the length of the userid.
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.
what is the lifespan of an access token in the FB oAuth API?
Not the extended offline permissioning, just a normal access token?
If you don't specify the offline permission, then the token is only valid while the user is signed in to Facebook and only until the expiry that gets passed back to you passes. I think it is somewhere around 2 hours generally but I haven't verified it. You can find more information from Facebook's documentation.
http://developers.facebook.com/docs/authentication/
User access token expiry is returned when the access token is issued (you see it appended to the end of the access_token). It is currently 2 hours, but that is subject to change. The key thing to remember is that access token can become invalid for a number of reasons and you need to make sure that you are prepared to handle that case. See the how-to for this at: https://developers.facebook.com/blog/post/500
App access tokens have no expiry right now, but I expect that we are going to change that and you should also be prepared to handle the case where this token becomes invalid.