How Do Refresh Tokens Work?
In OAuth, a refresh token is a key concept that grants offline access. This means a user’s session can be maintained and new tokens can be issued without requiring the user to re-authenticate with their credentials.
How Refresh Tokens Work
The process for obtaining and using a refresh token is as follows:
- Requesting Offline Access: The client application initiates an authorization request, including the offline_access scope. This request must be made using the Authorization Code Grant flow.
- User Authentication: The user authenticates by providing their credentials to the authorization server.
- Receiving the Authorization Code: The server returns an authorization code to the client application.
- Exchanging the Code for Tokens: The client exchanges this code for a full token set, which includes:
- An Access Token
- An ID Token
- A Refresh Token
Each of these tokens has an expiration period, which is typically configured on the authorization server. The access token usually has the shortest lifespan (e.g., minutes), while the refresh token is valid for a much longer period (e.g., days or months).
When the access token expires, the client application uses the refresh token to get a new one:
- The client sends the refresh token to the server’s token endpoint, using the refresh_token grant type.
- The server validates the refresh token and responds with a new access token and ID token, extending the user’s session.
This process is described in detail in RFC6749 Section 1.5.
How To Obtain A Refresh Token
In an Authorization Code Grant flow, refresh tokens are issued to clients that specifically request them. To receive a refresh token, two things must happen:
- The client must be configured to allowed to use the
offline_accessscope in the authorization server. - The client application or website must explicitly request the
offline_accessscope during the initial authorization request.
This means that when the client redirects the user to the authorize endpoint, the query string must include offline_access in the scope parameter, like this:
https://auth.yourserver.com/connect/authorize?client_id=...&...&scope=openid%20...%20offline_access&...
By default, after a successful authorization, the server returns an authorization code. The client then exchanges this code for an access token and an ID token at the token endpoint. When the offline_access scope is included in the initial request, the token endpoint will also return a refresh token in the response.
How To Obtain New Tokens With A Refresh Token
To obtain new tokens, you must send the refresh token to the /token endpoint. This request must include:
- Client Credentials: Both the client_id and client_secret.
- Grant Type: The grant_type must be set to refresh_token.
- Refresh Token: The refresh token itself.
- Scope (optional): You can include a scope if you want the new tokens to have a different set of permissions than the original. If you do this, the old refresh token will be revoked, and a new one will be provided in the server’s response.
Here’s an example of what a typical refresh_token request looks like:
POST /token HTTP/1.1
Host: typical-example.sandbox.entrypage.io
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIwThe server will typically respond with a JSON object containing the new tokens:
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 300,
"scope": "openid profile ...",
"id_token": "...",
"refresh_token": "..."
}Note: The expires_in returned in a token response applies only to the access token, not the ID or refresh token.
Storing The Refresh Token
A refresh token grants offline access, which means it can be exchanged for a new access token without the user needing to re-authenticate. Because of this capability, it’s important to carefully consider whether using refresh tokens is the right choice, especially when the device storing the token can’t be fully trusted.
When to use refresh tokens
Backend for Frontend (BFF) / Token Handler Pattern: If you’re using the BFF pattern to relay tokens upstream, you can store the refresh token securely on your backend.
Mobile Applications: For these types of clients, which run on the user’s device, you cannot securely store a client secret. This means extra caution is required to protect the refresh token. While it’s possible to store the token, you should implement additional security measures to make it as secure as possible.
Auth Time
Both the id_token and the access_token include an auth_time claim. This claim indicates the exact moment the user first authenticated, not when the tokens themselves were issued.
The Entrypage Implementation
Not all systems deal with refresh tokens similarly. The contents of the tokens in particular, or how to deal with changing client-configuration have only been defined to a limited extend in the OAuth and OpenID specification. That’s why the following topics are specific to Entrypage:
Dealing with Updates
Since authorization via a refresh token can last for days or even months, client configurations or user claims may change during that time. To address this:
- Tokens will always reflect the latest state of affairs. This means that if a user is removed from a directory or has their account disabled, a refresh token grant will fail.
- Authorization rules aren’t re-evaluated when tokens are renewed. The initial authorization is considered complete. If policies change, issued refresh tokens must be manually revoked.
- Client setting changes may impact token renewal. Changes to things like the grant_type or scopes can affect the renewal process.