Access Tokens and Refresh Tokens Explained for Beginners

Access Tokens and Refresh Tokens Explained for Beginners

Protocols and standards like OAuth 2.0 have revolutionized authentication by replacing traditional credentials with tokens, ensuring a more seamless and secure login experience. These standards rely on tokens to users controlled access to sensitive resources without exposing their actual credentials.

Within the OAuth framework, two primary token types Access Tokens and Refresh Tokens play a crucial role. While both serve authentication purposes, they function differently.

The most widely used format for OAuth 2.0 token types is the JSON Web Token (JWT), a compact and self-contained standard that securely transmits authentication-related data across platforms. Its efficiency and security make it the preferred choice for handling authentication in modern applications.

Now, let’s explore how Access Tokens and Refresh Tokens compare, highlighting their similarities and key differences.

What is an access token?

An Access Token is a short-lived token or a digital asset, typically a JWT, facilitating seamless access to resources through OAuth or other auth configurations. Basically it is used to authenticate and authorize API requests on behalf of a user. As these tokens act as keys that allow users to access sensitive information without repeated login requests in a browser.

The access token would typically contain a user identifier and a set of permissions or roles, depending on what the system uses. It would be stored only by the client and only in memory (i.e. lost on a full reload). The token is validated by the server on every authorized call and inspected to verify if the caller has permissions to perform the given action.

For example, when a user successfully logs into a website using valid credentials (username/password, etc.), the authentication server generates an Access Token. The logic for generating this token is usually implemented in the user schema.

The following example illustrates how to generate an Access Token in a Node.js backend server, integrating it within the user schema in MongoDB for authentication:

//The below method show  how Access Token is being generated in user schema.

/* According the below logic _id, email, username and fullName is being  
   taken as part of the credentials to generate the access token. */

userSchema.methods.generateAccessToken = function () {
  return jwt.sign(
    {
      _id: this._id,
      email: this.email,
      username: this.username,
      fullName: this.fullName,
    },
    process.env.ACCESS_TOKEN_SECRET,
    {
      expiresIn: process.env.ACCESS_TOKEN_EXPIRY,
    }
  );
};

Characteristics:

  • Short-lived: Typically expires within minutes to an hour for security reasons as it reduces risk in case of token leaks.

  • Used for Authorization: Sent in the Authorization header (Bearer <token>) of API requests.

  • Stored on Client-Side: Usually stored in memory, local storage, or session storage (though local storage is not recommended due to XSS attacks).

What is an refresh token?

A Refresh Token is a long-lived token used to obtain a new Access Token without requiring the user to log in again. They are usually issued together with access tokens and allow the system to generate new access tokens once the current one expires. Unlike access tokens, which are sent with each request, refresh tokens are stored securely on the authorization server.

Their primary role is to support long-lasting user sessions without requiring frequent authentication. However, it’s not mandatory to use access token and refresh token in OAuth implementations, but they enhance both user experience (UX) by enabling seamless re-authentication and security by reducing the exposure of long-lived access tokens.

The following example demonstrates how to implement Refresh Token generation in MongoDB within the user schema:

//The below method show  how Refresh Token is being generated in user schema.

/* As _id of the user is sufficient enough to generate the refresh token. */

userSchema.methods.generateRefreshToken = function () {
  return jwt.sign(
    {
      _id: this._id,
    },
    process.env.REFRESH_TOKEN_SECRET,
    {
      expiresIn: process.env.REFRESH_TOKEN_EXPIRY,
    }
  );
};

Characteristics:

  • Long-lived: Typically expires in days to weeks or even months.

  • Used for Token Renewal: Refresh tokens are sent only to a trusted or authorized backend to request a new access token. Unlike access tokens, they are not included in every request, ensuring enhanced security and reducing exposure to potential threats.

  • More Secure: Stored securely (e.g., HTTP-only cookies or secure storage mechanisms).