Authentication - Refresh Tokens

The Refresh Tokens are used to obtain a renewed Access Token, so the user doesn’t have to re-enter their login credentials.

Utility

When a user signs in, the authentication server sends them an Access Token which is used to authenticate its API requests, but the Access Token has a short duration, so the user has to re-enter their login credentials again to get another Access Token.

To avoid this scenario, the Refresh Tokens can be used, so, when the user signs in, the authentication server should sends them an Access Token and a Refresh Token, which is used to generate a renewed Access Token once it has expired.

Characteristics

  • When a user signs in, they receive a Refresh Token along with the Access Token.
// API response when the user signs in:
{
  "access_token": "abcabc",
  "refresh_token": "abcabc"
}
  • Refresh Tokens have a lifetime of days or weeks.
  • Refresh Tokens don’t increase the duration of the Access Tokens, but the authentication server checks the Refresh Token validity and if it is, it responds with a new Access Token.
  • Refresh Tokens must be sent only to the authentication server (Never to the resource server).
  • The authentication server must have a POST endpoint that renews the Access Tokens, and the Refresh Tokens must be sent only to this endpoint and just when the Access Token has expired.
  • Refresh Tokens must be securely stored on the client.
  • Keep a Refresh Tokens secure is very important because if one of them is exposed, the attacker can generate an infinite number of Access Tokens of the compromised user.

Refresh Token rotation

This method improve the security of the Refresh Tokens, it consists on rotating them as they are used, therefore these must be invalidated after being used to generate an Access Token.

For a Refresh Token to be marked as used, it must be stored in persistence (Database).

This method consists of this process:

  1. User signs in by first time (POST /sign-in):

    1. Auth server creates an Access Token and Refresh Token.
    2. Auth server stores the recently created Refresh Token on persistence.
    3. Auth server responds with the recently created Access Token and Refresh Token.
  2. The user petitions use their Access Token, but when it expires (POST /refresh):

    1. Auth server validates the Refresh Token (Not expired nor used).
    2. Auth server creates an Access Token and Refresh Token.
    3. Auth server update the used Refresh Token marking it as used on persistence.
    4. Auth server responds with the recently created Access Token and Refresh Token.

Refresh Token properties

{
  "id": "e330ab2c-1d98-445b-bae9-64ae55a1ae17",
  "createdAt": "2022-02-13T10:08:20+00:00",
  "duration": 86400,
  "ipAddress": "192.168.0.1",
  "replacedAt": "2022-02-10T12:08:20+00:00",
  "replacedBy": "f0c6c30b-acf4-41c9-8ad9-f0d9720fc91b"
}
  • id: Refresh Token unique ID.
  • createdAt: Refresh Token creation date.
  • duration: Refresh Token lifetime duration in seconds.
  • ipAddress: Client device IP address that generated this Refresh Token.
  • replacedAt: Nullable date when the Refresh Token was used to generate a new Access Token.
  • replacedBy: Nullable ID of the new Refresh Token generated from it.

The replacedAt and replacedBy properties are null until the Refresh Token is used.

References