Access Token vs Refresh Token

Rohit KumarRohit Kumar
3 min read

In modern web and mobile applications, authentication is the first step, but maintaining a secure session is the real challenge. That’s where Access Tokens and Refresh Tokens come into play. Let's dive into what they are, how they work, and why they matter.

What is an Access Token?

An Access Token is a short-lived credential used to access protected resources like user profiles, dashboards, APIs, etc.

  • Issued by: Authorization server (e.g., OAuth provider, custom backend)

  • Format: Mostly JWT (JSON Web Token)

  • Validity: Typically 5 to 15 minutes

GET /user/profile
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...

What is a Refresh Token?

A Refresh Token is a long-lived token used to obtain new access tokens when the old ones expire.

  • Never used to access resources directly

  • Stored securely (preferably in httpOnly cookies)

  • Lifespan: Hours, days, or even months

POST /auth/refresh-token
Body: { "refreshToken": "eyJhbGciOi..." }
Response: { "accessToken": "new_access_token_here" }

Difference Between Access Token and Refresh Token

FeatureAccess TokenRefresh Token
PurposeAuthorize API/resource accessGet a new access token
ExpiryShort (minutes)Long (days/months)
UsageSent in headers for every callSent only when access token expires
Storage (Frontend)In-memory or localStoragehttpOnly cookie (preferred)
Security RiskLower (short-lived)Higher (must be protected well)
Exposure RiskEasy to rotateHarder to revoke if stolen

How They Work Together

  1. ✅ User logs in → gets Access Token & Refresh Token

  2. ⏳ Access Token expires after 15 minutes

  3. 🔁 App uses Refresh Token to get a new Access Token

  4. 🔐 Keeps session alive without asking user to log in again

When to Use What?

ScenarioRecommended Setup
Public API (short session)Access Token only
SPA / React appAccess + Refresh Token
Mobile app (e.g. Flutter)Access + Refresh + Secure Storage
Banking/FintechShort Access + Rotating Refresh

Similarities

  • Both are issued after successful authentication

  • Both are signed (often using JWT)

  • Both can be revoked by backend

  • Both should be protected against XSS/CSRF

Token Flow Chart

Below is a simplified token lifecycle (shown in the uploaded chart):

  1. Login → Token issued

  2. Token sent with each request

  3. If expired → refresh token used

  4. New token issued → loop continues

  5. Logout or refresh expiration → invalidate

Backend (Node.js + Express)

// Issue tokens
const accessToken = jwt.sign({ id: user._id }, "secret", { expiresIn: "15m" });
const refreshToken = jwt.sign({ id: user._id }, "refreshSecret", { expiresIn: "7d" });

Frontend (Axios Interceptor)

axios.interceptors.response.use(
  res => res,
  async error => {
    if (error.response.status === 401) {
      const res = await axios.post("/auth/refresh-token", { token: getRefreshToken() });
      setAccessToken(res.data.accessToken);
      return axios(error.config); // Retry original request
    }
    return Promise.reject(error);
  }
);

Best Practices

  • 🔒 Store Refresh Token in httpOnly cookies (not localStorage)

  • 🔄 Rotate refresh tokens on every use

  • 🧯 Revoke on logout

  • 🔐 Use HTTPS always

  • ✅ Implement token blacklist for compromised tokens

Real-World Applications

AppToken Usage
GmailUses both tokens for seamless auth
GitHubShort-lived access tokens for CLI sessions
SpotifyAccess token for playback, refresh for session renewal
Firebase AuthUses access & refresh under the hood

Access Tokens give you access.
Refresh Tokens help you keep it.

Together, they balance security and user experience.

If you're building modern apps — especially SPAs or mobile — understanding this duo is essential.

0
Subscribe to my newsletter

Read articles from Rohit Kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rohit Kumar
Rohit Kumar