1. Overview

A JSON Web Token (JWT) is a standard that defines a compact and secure way of transmitting data along with a signature between two parties. A JWT can contain any information in JSON form, also known as JWT claims. Typically, JWTs have an expiration time or exp claim, ensuring that they’re valid for a particular duration.

However, one of the challenges in JWT-based systems is managing the token expiration and ensuring continuous user sessions. This is where the role of a refresh token becomes pivotal.

In this tutorial, we’ll examine the significance of a refresh token in JWT-based authentications. Additionally, we will delve into the potential issues with token expiration and discuss how a refresh token addresses these challenges. 

2. Understanding JWT

JSON Web Token (JWT) consists of three parts – the header, the payload, and the signature. A JWT looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

It looks like gibberish, but it’s a very compact, printable representation of a series of claims, along with a signature to verify its authenticity.

Here is the basic flow of JWT authentication:

  1. The client initiates the authentication process by sending a request to the server along with user credentials
  2. Upon verifying the credentials, the server creates a signed JWT and sends it back to the client
  3. The client stores the received token in the browser
  4. With each subsequent request, the client includes the token in the request sent to the server
  5. The server validates the token, granting access to the client if the token is valid

Consider a scenario where our application requires data from Gmail. We authenticate ourselves on the Gmail authentication server to access this data by providing credentials. Upon successful authentication, Gmail issues a JWT, which our application uses to retrieve the desired data. The issued JWT token will contain the following claims/JSON payload:

{
    "iss": "https://accounts.google.com",
    "azp": "123.apps.googleusercontent.com",
    "aud": "123.apps.googleusercontent.com",
    "sub": "10769",
    "at_hash": "HK6E_P6Dh",
    "email": "[email protected]",
    "email_verified": "true",
    "iat": 1453987654,
    "exp": 145398965,
    "nonce": "1234567-234545-2490358",
    "hd": "baeldung.com"
}

Here, the exp claim represents the expiration time, ensuring that the issued token is valid for a specified duration. Once a JWT token expires, the user must re-authenticate to obtain a new one.

The expiration features enhance security, but they also introduce challenges for long-lasting user sessions. Let’s consider a scenario where users actively engage with the application, and their token expires. Asking the user to log in again can negatively affect the user experience.

3. The Role of Refresh Tokens

Refresh tokens offer an elegant solution to the challenges posed by token expiration. These long-lived tokens are used to obtain a new access token when the current one expires. Now, when users log in, the server issues both a short-lived JWT (the access token) and a long-lived refresh token. Both tokens are sent to the clients when a user is granted access.

When users attempt to access a resource, they include the JWT access token in each request. Once the JWT expires, the client uses the refresh token to request both a new JWT and a new refresh token. This process is known as refresh token rotation.

4. Access and Refresh Token

The primary purpose of an access token is to grant secure access to protected resources on behalf of a user. These tokens are usually short-lived and may have an expiration date embedded in them. On the other hand, refresh tokens are typically long-lived and allow clients to request new access tokens.

The fundamental distinction between access and refresh tokens lies in the ease of independently validating access tokens.

An access token, especially one with a signature like a signed JWT, may be validated by a resource server, eliminating the need for interaction with the authorization server. The authorization server issues tokens to client applications on behalf of a resource owner to authenticate subsequent API calls to the resource server. The resource server, on the other hand, is responsible for hosting and providing access to protected resources based on the validity of the access token.

Refresh tokens need to communicate with the authorization server for validation. This separation of validation from authorization server queries allows for improved latency and simplified access patterns.

5. Refreshing an Expired Access Token Using Refresh Token

Let’s take a look at how the access token gets refreshed with the help of the figure below:

JWT Refresh Token Flow

The flow in the above figure includes the following steps:

  1. The client gets an access token by authenticating with the authorization server and providing an authorization grant
  2. The authorization server verifies the client’s identity and validates the authorization grant. If the grant is valid, the server issues both an access token and a refresh token. An authorization grant is a credential representing the resource owner’s consent for the client’s application to access protected resources on their behalf
  3. The client requests a protected resource from the resource server by providing the access token
  4. The resource server verifies the access token and, upon validation, fulfills the request
  5. Steps 3 and 4 are reiterated until the access token reaches its expiration. If the client knows the access token expiration, it proceeds to step 7; otherwise, it initiates another request for a protected resource
  6. Due to the access token being invalid, the resource server responds with an error indicating the token’s invalidity
  7. The client seeks a fresh access token by authenticating itself with the authorization server and presenting the refresh token. The specific authentication criteria for the client depend on its type and the policies defined by the authorization server
  8. The authorization server verifies the client’s identity and validates the refresh token. If the refresh token is valid, the server issues a new access token and, optionally, a new refresh token

6. Security Considerations

Security considerations play a pivotal role in designing and implementing any authentication system using refresh tokens. Here’s an overview of the security considerations involved with the Refresh token:

  • Securing refresh tokens is crucial for protecting sensitive user data. When storing refresh tokens on the server, we should implement strong encryption methods and adhere to best practices
  • When transmitting a refresh token between the client and servers, it’s essential to use secure channels. Using HTTPS encrypts the communication. preventing man-in-the-middle attacks
  • Rotating tokens includes routinely changing refresh tokens to enhance security. This approach minimizes the timeframe for potential attackers to exploit tokens, thereby decreasing the risk of prolonged token misuse

7. Token Rotations

Let’s take a look at the various token rotation strategies.

7.1. Periodic Rotation

In this approach, we rotate refresh tokens at predefined intervals, regardless of whether the token is still valid. This allows us to reduce the window of opportunity for attackers to misuse a token. If a token is compromised, its usefulness is limited by the rotation frequency.

7.2. Graceful Rotation

In this approach, we implement token rotation in a way that doesn’t disrupt ongoing user sessions. This allows us to smoothly transition from the old token to the new token without forcing users to authenticate. It provides a seamless experience without frequent authentication, which can be inconvenient for the users.

7.3. Selective Rotation

Instead of rotating the token periodically, we rotate tokens selectively based on certain criteria, such as security events, user activity, etc. It helps us target users or scenarios that can pose a higher security risk.

7.4. Token Versioning

We can also introduce a versioning mechanism for refresh tokens. When a token needs to be rotated, we’ll increment its version, and then we’ll use the updated version for subsequent requests. It’ll allow us to have a phased rollout of new tokens without causing immediate disruption to all active sessions.

8. Conclusion

In this article, we’ve discussed the significance of refresh tokens and potential challenges with token expiration. Refresh token plays a vital role in maintaining persistent user sessions without compromising security.

Refresh tokens are crucial in crafting secure, reliable, and user-friendly authentication systems.