Skip to main content

Command Palette

Search for a command to run...

Access Tokens vs Refresh Tokens: The Missing Piece Most JWT Tutorials Don't Explain

Updated
4 min read
Access Tokens vs Refresh Tokens: The Missing Piece Most JWT Tutorials Don't Explain
S
I am student at DTU , India

When I first learned JWT authentication in MERN, I understood how to generate a token after login. What I didn't understand was why we need both an Access Token and a Refresh Token.

If a user is already logged in, why does the server keep asking for tokens? Why not just trust that the user logged in earlier?

After implementing authentication middleware and building login/logout flows, the answer finally clicked.

In this article, I'll explain Access Tokens and Refresh Tokens from a practical developer's perspective

most of the information i got is by reading some articles , tutorials and llms

The Fundamental Problem

HTTP is stateless.

Every request sent to the server is independent.

Imagine a user logs in:

POST /login

The server verifies the email and password and generates a JWT.

The user then makes another request:

GET /profile

The server doesn't automatically remember who sent this request.

It only sees:

Incoming Request

The server needs proof that the request is coming from an authenticated user.

That's where tokens come in.


Access Token

An Access Token is a short-lived JWT used to access protected routes.

Example payload:

{
  "_id": "user123"
}

The token is sent with every protected request:

Authorization: Bearer ACCESS_TOKEN

When the request reaches the server, middleware verifies:

  1. Does a token exist?

  2. Was it signed by our server?

  3. Has it expired?

  4. Does the user still exist?

Example middleware:

const decodedToken = jwt.verify(
  token,
  process.env.ACCESS_TOKEN_SECRET
)

const user = await User.findById(decodedToken._id)

If everything is valid:

req.user = user
next()

The request proceeds.


Why Not Use Access Tokens Forever?

Imagine an access token that lasts for 30 days.

If an attacker steals it:

Attacker = Full Access For 30 Days

That's a security nightmare.

Instead, access tokens are intentionally short-lived:

5 minutes
15 minutes
30 minutes
1 hour

Even if stolen, the damage is limited.


Refresh Token

A Refresh Token exists for one purpose:

Generate new Access Tokens.

Instead of forcing users to log in every 15 minutes, we issue:

Access Token  → 15 minutes
Refresh Token → 7-30 days

When the Access Token expires:

401 Unauthorized

The frontend sends the Refresh Token to a refresh endpoint:

POST /refresh-token

The server verifies the Refresh Token and issues a new Access Token.

The user stays logged in without noticing anything.


The Real Difference

Access Token Refresh Token
Used on every API request Used only to get new access tokens
Short lifespan Long lifespan
Higher exposure risk More protected
Expires quickly Keeps user logged in
Sent frequently Sent rarely

Why Do We Still Query the Database?

One question confused me while building authentication middleware.

If the JWT already contains the user's ID, why do we still query MongoDB?

const user = await User.findById(decodedToken._id)

The reason is simple.

A token only proves:

This user was valid when the token was created.

It does not prove:

  • The account still exists

  • The user wasn't banned

  • Permissions haven't changed

The database remains the source of truth.


What Happens During Logout?

Many beginners think logout means:

res.clearCookie("accessToken")

But that's only part of the story.

The real logout mechanism is usually:

user.refreshToken = undefined
await user.save()

Why?

Because if someone steals a Refresh Token, we need a way to invalidate it.

Deleting it from the database prevents future token refreshes.


Advanced Concept: Refresh Token Rotation

Most tutorials stop here.

Production systems often use Refresh Token Rotation.

Instead of reusing the same Refresh Token forever:

Refresh Token A
      ↓
Generate Access Token
      ↓
Generate Refresh Token B
      ↓
Invalidate Refresh Token A

This reduces the impact of stolen Refresh Tokens.

Many large-scale applications use this approach for additional security.


Final Mental Model

Think of authentication like entering a secure building.

Access Token  = Temporary Entry Pass
Refresh Token = Master Pass To Get New Entry Passes

The Access Token gets you through security checkpoints.

The Refresh Token allows you to obtain a new Access Token without proving your identity again.

Together, they provide both:

  • Security (short-lived access)

  • Good user experience (persistent login)

And that's why modern applications use both instead of relying on a single token.