Access Tokens V/S Refresh Tokens

To make it more easy to Understand, I am using example of login functionality which is used in many cases.

  1. Logging In :

When you log into a web application, the server verifies your credentials after successfully authentication, the server sends you Access Tokens and Refresh Tokens.

Access Token : Like a temporary ticket that grants you access to app's features.

Refresh Token : Acts like a backstage that allows you to get a temporary ticket without logging again and again.

Here is an example code to store the Tokens in your API which is running on server.

Example Code:

// Example: User Login to Get Tokens
fetch('https://api.example.com/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    username: 'user',
    password: 'pass'
  })
})
.then(response => response.json())
.then(data => {
  const accessToken = data.accessToken;
  const refreshToken = data.refreshToken;
  console.log('Access Token:', accessToken);
  console.log('Refresh Token:', refreshToken);
})
.catch(error => console.error('Error:', error));

2. Using the Access Token

Whenever you want to access a protected resource (like user data), you use the access token.

Example in Code:

// Example: Using Access Token to Fetch Data
fetch('https://api.example.com/user/data', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer ACCESS_TOKEN'
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

3. Refreshing the Access Token

Access tokens are short-lived for security reasons. When it expires, you use the refresh token to get a new access token without needing to log in again.

Example in Code:

// Example: Using Refresh Token to Get a New Access Token
fetch('https://api.example.com/auth/refresh', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    refreshToken: 'REFRESH_TOKEN'
  })
})
.then(response => response.json())
.then(data => {
  const newAccessToken = data.accessToken;
  console.log('New Access Token:', newAccessToken);
})
.catch(error => console.error('Error:', error));

4. Logging In Again

When you log in again (e.g., after logging out or the refresh token expires), both the access token and the refresh token are renewed.

Example in Code:

// Example: Logging In Again to Get New Tokens
fetch('https://api.example.com/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    username: 'user',
    password: 'pass'
  })
})
.then(response => response.json())
.then(data => {
  const newAccessToken = data.accessToken;
  const newRefreshToken = data.refreshToken;
  console.log('New Access Token:', newAccessToken);
  console.log('New Refresh Token:', newRefreshToken);
})
.catch(error => console.error('Error:', error));

5. Key Points

  • Access Token: Short-lived, used for accessing resources.

  • Refresh Token: Long-lived, used to get a new access token.

  • Token Renewal: Logging in again updates both tokens.

6. Security Considerations

  • Access Token: Store in memory or session storage; avoid local storage to prevent XSS attacks.

  • Refresh Token: Store securely (e.g., HttpOnly cookies) to prevent theft.

7. Real-Life Analogy

Imagine you’re visiting a secure office building:

  • Access Token: Like a visitor badge that’s valid for a day.

  • Refresh Token: Like a longer-term pass that lets you get a new visitor badge without signing in at the front desk each time.

  • Logging In Again: Like renewing your long-term pass, giving you a new visitor badge and a new long-term pass.

Summary

When you log in, you get both an access token and a refresh token. The access token lets you access the app’s features, while the refresh token lets you get a new access token without logging in again. When you log in again, both tokens are renewed, ensuring continued secure access to the application.

This approach keeps your app secure while providing a smooth user experience.