In OAuth 2.0, you control access to your application's protected resources by using access tokens. Access tokens are the credentials representing the authorization given to an application. They contain the granted permissions in the form of scopes with a specific duration.
In most cases, an access token should be short-lived, so your application reduces the time window risk of providing access to restricted resources when an access token is compromised.
In the scenario of an expiring access token, your application has two alternatives:
Depending on your application’s needs - both options are valid. For example, you may ask your application users to re-authenticate each time a token expires for sensitive applications when the risk of damage is high if an access token is compromised. Using such an approach comes with a significant downside as this means you can't use it for applications that need offline access to protected resources; the end-user needs to be involved each time.
In this blog post, we will focus on alternative number two: The authorization server automatically issues a new access token once it expires.
This approach guarantees a seamless user experience. You're not asking the user to re-authenticate each time the access token expires, but how do you provide authorization without doing so? As you may already guess from this blog post title, using a refresh token.
A refresh token is used in the following scenarios:
Access tokens with a limited lifespan will eventually expire, removing access to the protected resources needed by your application users. If your application's users need access beyond the lifespan of an access token, they can retrieve a new one using a refresh token. That's their single purpose; you can't use a refresh token to access protected resources. That's the access token's responsibility. Unlike access tokens, refresh tokens have a longer lifespan.
Certain services that support the OAuth 2.0 protocol, like Google, restrict the number of refresh tokens issued per application user and per user across all clients. Refresh tokens expire after six months of not being used. Another example is LinkedIn API, where by default, access tokens are valid for 60 days, and programmatic refresh tokens are valid for a year.
Support of OAuth refresh tokens is available in the following authorization grant types:
As a good security practice, Implicit grant type is not longer recommended, see our Single Page Application section for more details.
Let’s review how refresh token works in the context of your application by following this diagram:
There is a repetition of steps from 5 to 8 each time an access token is invalid.
Sample of an OAuth response that includes a refresh token:
{
"access_token": "HEuoFdfRhOwGA0QNn",
"refresh_token": "hgTam-tuT8CvFej9-XxGyqeER_7j",
"token_type": "bearer",
"expires_in": 86400
}
The "expires_in"
value is the number of seconds the access token will be valid.
Some services that supports refresh token expiration will return the expiration for the access token and the refresh token.
{
"access_token": "HEuoFdfRhOwGA0QNn",
"refresh_token": "hgTam-tuT8CvFej9-XxGyqeER_7j",
"token_type": "bearer",
"expires_in": 86400,
"refresh_token_expires_in": 525600
}
Now that we understand the primary role of a refresh token, let's review some recommended best practices.
Storing of Refresh Tokens should be in long-term safe storage:
A refresh token is used to get a new non-expired access token with the same credentials. Your application shouldn’t request additional scopes not issued in the original expired access token. The Authorization Server already knows the original scopes granted to the access token.
If the Authorization Server returns a new refresh token as part of the new token request, store the new refresh token; otherwise, assume the current refresh token used remains valid.
Refresh tokens must be kept confidential in transit using TLS and shared only among the Authorization Server and the Client to whom the refresh tokens were issued.
Refresh token rotation is a security measure offered to mitigate risks associated with leaked refresh tokens, single page applications (SPA) are especially vulnerable to this (Read more about it in our Single Page Application section). An attacker can access a refresh token by using a replay attack. The rotation mechanism implies that a refresh token can be used only once, giving the authorization server the ability to detect refresh tokens reuse.
The authorization server can detect a breach from a compromised refresh token by identifying an invalid refresh token usage, either by the legitimate client or the attacker. When a new refresh token is issued, the authorization server retains the previous one. With this technique, the authorization server can detect a breach from a compromised refresh token by identifying an invalidated refresh token usage, either by the legitimate client or the attacker. (Reuse detection).
When the authorization server detects a refresh token reuse, it immediately revokes the refresh token and denies access to subsequent requests to the attacker and the legitimate user. There is no way to detect if the refresh token is coming from a trusted source, so the legitimate user must authenticate again. Take into consideration this is not a bulletproof mechanism but increases the security of your application significantly.
Let’s understand how refresh token rotation works in the context of an OAuth flow:
Single Page Applications, or SPA for short, are popular. They're mostly the defacto standard for building modern web applications today. They're inherently insecure due to the underlying nature of being public clients (as opposite of confidential clients) running on the client-side. Today, the recommended approach is to use the authorization code flow alongside PKCE. This flow now enables a SPA to obtain refresh tokens.
A malicious attacker can use a compromised refresh token to issue a new access token to request protected data to the resource server. The authorization server can contain this risk by detecting refresh token reuse using refresh token rotation. If your application uses refresh token rotation, it can now store it in local storage or browser memory. You can use a service like Auth0 that supports token rotation.
There are several reasons a user needs to remove authorization access to their account from your application:
Popular authorization and authentication service providers like Auth0 support refresh token removal via token/revoke
endpoint.
You’ve learned the best practices of refresh token management. It’s possible to offer your application users a seamless and secure experience. By following these basic principles, you will sleep better 😴, confident you’re handling your refresh tokens properly.