I'm working with an API that uses OAuth2, provides an access token that expires in 3600 seconds, and provides a refresh token with it. Originally, I'd waited for an API call to fail in a way that indicated the access token was expired and then tried to refresh the access token using the refresh token. This has become problematic when the access token is expired and several API calls are made concurrently (each call separately triggers a refresh and most of the calls fail).
Would it be better to automatically refresh the access token using the refresh token after 3600 seconds? (Or 3599 seconds or 3601 seconds?) Is there a different paradigm I should be using for refreshing the access token?
Ideally, the client should have sufficient smarts to not use an expired access token. Fortunately the response from your OAuth AS's token endpoint should include the expires_in attribute to confirm that the expiry will be in 3600 seconds. E.g.:
{"token_type":"Bearer","expires_in":3600,"refresh_token":"p8BPdo01kkjh6fhatclD3wwBEQblm4kL4ctYRVlrHo","access_token":"9XebAAXeu6hQOAiwmOk8vdhRyUFV"}
Since this JSON response is generated by the server, there's a chance that the transmission back to the client has taken time, and thus the "expires_in" value may be smaller than it appears.
Given that, I'd recommend that you have some sort of buffer (say 5-10 seconds) before expiry to automatically use your refresh token to request a new access token.
I may have used the following scenario. There will be access failures due to access token validation error but those errors will be minimal.
App1 invokes the token api with password grant type and get the access token and refresh token pair (accto1/refto1)
App2 also do the same at the starting up of the execution (accto1/refto1)
When the access token is expired for App1, he may do the refresh token by invoking the token api with refresh token grant type and with his existing refresh token (refto1) and he will retrieve a new pair of access token and refresh token. (accto2/refto2)
When App2 also reaches the instance when his access token is expired, he will also try the refresh token grant with the refresh token he already has (refto1) but he will get an authorization error since that refresh token is now expired.
When either of the apps get this error then app needs to realize that someone else has refreshed the token so at this moment the app needs to make a call with the password grant to retrieve the new access token / refresh token pair in action. This time as in the example the App2 will also retrieve the same access token and refresh token pair that the App1 has previously received for his refresh token grant. (accto2/refto2)
Related
As we know that access token gives the client to access resources from resource server, I would like to know the contents and the process that happens with refresh token to get new access token.
I was tryging to experiment how oauth2 works, but got stuck at what refresh token does.
I would like to know the contents and the process that happens with
refresh token to get new access token.
Refresh token are generally opaque token (random unique string).
Refresh token is used to get new access token from the Authorization Server. Refresh tokens typically remain valid for longer time as compared to access token. In a typical client-server flow, when the access token expired, server reject the request then client uses the earlier obtained refresh token to get a new access token from Authorization Server. By doing so authentication between client and server remain uninterrupted and no re-authentication needed. Once the refresh token expired, client has to go through the complete authentication flow which usually require user intervention.
If I refresh an OAuth2 access token, is the current (old) token valid or invalid? Will the old access token valid until it receive its expired time?
In my applications there are multiple threads that use the same access token parallel. If the access token is going to its live end, for example there is only a minute until it expired, then one thread request a new access token with an refresh token.
Does I need a read lock on the access token to prevent a refresh on using the access token?
My problem is figuring out when to refresh the access token.
I have read that I should refresh the new access token before each request, but it says elsewhere that this is not recommended. So my question is whether I should refresh the access token before each request or send the request and after receiving the 401 Unauthorized status refresh the access token and retry the request to the specified resource.
You can get the expiry time from the access token (usually at a field called exp and is formatted as unix timestamp). So whenever you prepare sending a HTTP request to the resource server , you can check that if the access token is already expired or about to be expired very soon (e.g 60 seconds).
If yes, try to use the refresh token to get a new access token , and update the returned new access token and refresh token that are stored inside your app. Otherwise , just keep using the existing access token.
You can do either way, you know when you access token is about to expire and for example 1 minute before, you use the refresh token to get a new set of refresh/access tokens.
Doing it on a 401 is also an option but that means that you need to do an extra request and you also have some race-conditions to watch out for, as in many configurations you only allow a one-time use of a refresh token (you get a new refresh token each time). So with the 401 approach, you need to make sure you don't sent away many concurrent requests to get new tokens for the same user.
Once I've completed the OAuth flow by obtaining authorization from the user and then creating an access token, how do I obtain another token without asking the user for authorization again? I thought the user's account on Smartsheet would remember that they trusted the application, but that doesn't seem to be the case. I'm new to OAuth so I'm sorry if I'm missing something obvious.
Thanks!
Access tokens retrieved via the OAuth flow are valid only for a certain period of time -- you (i.e., your application) can refresh a token before it expires in order to prevent the end-user from having to provide authorization again.
When you issue a GET Token request to obtain an access token, the response contains not only the token itself, but also information to indicate how long the token is valid (the expires_in property indicates the number of seconds until the token expires) and a refresh_token property value that you'll need in order to refresh the token.
To prevent the user from having to provide authorization again, simply refresh the token before it expires, and then use the new (refreshed) token value in subsequent API requests. Note that each token you obtain (whether it's the original token or a refresh token) will always expire in a finite amount of time, thereby requiring that you refresh the token in order for your application to maintain user authorization.
I am implementing an oauth server using spring oauth. I notice that spring's implementation re issues the same access token if not expired from the token endpoint. However the behavior is different while refreshing access tokens. A new token is reissued each time, are there any concerns to keep in mind if I were to reissue the same un expired access token on receiving a valid refresh request.
The OAuth Spec section-6 specifies that:
The authorization server MAY issue a new refresh token, in which case
the client MUST discard the old refresh token and replace it with the
new refresh token. The authorization server MAY revoke the old
refresh token after issuing a new refresh token to the client. If a
new refresh token is issued, the refresh token scope MUST be
identical to that of the refresh token included by the client in the
request.
There does not seem to be a requirement that the access token is brand new.
I think the main concern is to ensure that you do not change the expiration date on an existing token. And that you correctly return to the client an accurate expires_in property which reflects when the token will expire.
In addition, it might make the semantics confusing for clients. The refresh is usually done when a token is expired, and the client wants a new one.
I can imagine some odd edge cases. A client could send a request to refresh a token a few seconds before it is expired (perfectly valid logic for a client), but still receive back the same token which is almost expired.