🌐 Understanding Tokens and Cookies in the MERN Stack — A Simple Guide for Beginners

Virendra YadavVirendra Yadav
3 min read

Hey Developers! 👋
If you're learning the MERN stack (MongoDB, Express.js, React.js, Node.js), chances are you’ve heard about access tokens, refresh tokens, and cookies.

But let me guess —

“Yeh token hota kya hai?” or “What exactly is a token?”
“Cookies kyu use karte hain?” or “Why do we use Cookies?”
“Kaunsa token kaha use hota hai?” or “Which token is used where?”

If that sounds like your situation, then this blog is just for you.
Let’s break it all down in simple talks, like how we discuss things with a Tea in hand! ☕


🔐 What is a Token?

A token is like a digital pass.
When a user logs in, the server gives them a token as proof —
"Bhai tu login ho gaya hai, ab yeh le tera access pass!"

There are mainly two types of tokens:

1. Access Token

  • Short-lived (15 mins, 1 hour, etc.)

  • Used for accessing protected routes

  • Sent in the Authorization header with each request

Example:
Authorization: Bearer <access_token>

2. Refresh Token

  • Long-lived (7 days, 30 days, etc.)

  • Used to generate new access tokens after the old one expires

  • Generally stored in a httpOnly cookie for security

  • Not sent with every request — only when needed


A cookie is a small piece of data stored in the user's browser.

In MERN apps:

  • We store refresh tokens inside cookies, safely (httpOnly, Secure)

  • So, the frontend doesn’t have to handle it manually

  • Automatically goes with requests made to the server


🔁 Full Login Flow with Access & Refresh Tokens

Let’s understand the flow after the user logs in:

✅ User Logs In

  • Server verifies email/password

  • Generates:

    • accessToken (short life)

    • refreshToken (long life)

  • Access token is sent in response

  • Refresh token is stored in httpOnly cookie


🟢 User Makes Protected Requests

  • Frontend sends accessToken in headers

  • Server verifies it using jwt.verify(token, ACCESS_SECRET)


❌ Access Token Expires

  • Now user can’t access protected routes

  • Frontend silently sends refreshToken (from cookie) to /refresh-token


🔄 New Access Token Issued

  • Server verifies refresh token

  • If valid, sends a new access token

  • No need to log in again!


❌❌ Refresh Token Also Expires

  • Now user has to login again

  • That’s the only option

  • Old tokens are useless


🧠 Why Not Just Use Access Token Forever?

Simple — security!

If someone steals your access token:
They can act as you! 😨

But if the token expires fast, damage is limited.

And storing the refresh token in cookie helps:

  • It's not accessible from JavaScript (httpOnly)

  • Cannot be easily stolen using XSS attacks


🏁 Wrapping Up with a Simple Example:

Imagine you enter an office building:

  • The guard gives you an ID card after checking your details.
    → This is your Access Token – lets you move around, but expires soon.

  • When it expires, you show your entry pass at the desk to get a new one.
    → That’s your Refresh Token – used to get a fresh Access Token.

  • A small sticky note on your shirt says "verified" so guards don’t ask again.
    → That’s a Cookie – helps the system remember you.


In short:

🔑 Access Token = Temporary ID
♻️ Refresh Token = Gets you a new ID
🍪 Cookie = Sticky note to remember you


That’s the magic behind login systems — simple, smart, and secure! 🙌
Check out more tech insights at Chai aur Code!

This blog is also inspired by the amazing work done by the https://x.com/Hiteshdotcom.

0
Subscribe to my newsletter

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

Written by

Virendra Yadav
Virendra Yadav

🚀 Full-Stack MERN Developer | Passionate about building powerful apps with React.js, Node.js & MongoDB.