This content originally appeared on DEV Community and was authored by Sylwia Laskowska
A while ago in a technical interview I got asked:
“Can you walk me through how authentication and authorization actually work under the hood?”
And like many devs I knew just enough to plug in Auth0/NextAuth etc… but not enough to explain the “why” behind the flow.
This series is the version I wish I had back then — plain English, no magic ✨, just a mental model that sticks.
Why does the frontend need AuthN? 🤷♀️
Because the frontend knows nothing about you.
To your browser, you’re just:
- a tab with JavaScript,
- a user… or a hacker,
- or possibly a fridge 🧊 with Chrome 😅
It needs someone trusted to say “yes, that’s really Sylwia.” → that “someone” is the IdP.
AuthN vs AuthZ 🆚
| Name | Fancy | Human |
|---|---|---|
| AuthN | Authentication | “Who are you?” 👤 |
| AuthZ | Authorization | “What are you allowed to do?” ✅ |
👉 The frontend does NOT authenticate you — it just starts the process and carries tokens.
👉 The API is the thing that actually says “yes/no” to an action.
Who does what? 🧩
| Actor | Job |
|---|---|
| IdP | Knows the user + issues tokens |
| Frontend | Asks for tokens & stores the right ones |
| API | Validates access token & allows/blocks actions |
Analogy 🛂
| Real World | In Auth |
|---|---|
| Passport office | IdP |
| Border control | API |
| Traveler sweating at customs 😅 | Frontend |
The three token types 🎟️
| Token | What it is | Analogy |
|---|---|---|
| ID Token | who you are | passport / ID |
| Access Token | permission | visa / entry stamp |
| Refresh Token | ability to renew | VIP wristband 🎤 |
⚠️ The ID token is for the frontend only.
The API doesn’t care about your life story — it cares about the access token ✅
Where do tokens live (and why not localStorage)? 🏠
❌ localStorage = “please rob me” 🏴☠️
Super convenient… also super easy to steal:
localStorage.getItem("access_token")
One tiny XSS → 💸 token gone.
And what about sessionStorage? 🤔
A common question is: “If localStorage is risky, is sessionStorage safer?”
Answer: No — same problem.
| Storage | Can JS steal it? | XSS resistance |
|---|---|---|
| localStorage | ✅ yes | ❌ weak |
| sessionStorage | ✅ yes | ❌ weak |
| HttpOnly cookie | ❌ no | ✅ strong |
sessionStorage only dies when the tab closes — it doesn’t protect against theft during the session.
So it doesn’t make tokens safer, just shorter-lived loot.
✅ Access Token → in memory 🧠
What it is: “permission” – proof you can call the API
Where it lives: in memory (JS variable, not storage)
Lifetime: short: ~5–15 min (sometimes up to 30)
Why short?: if stolen → damage window stays tiny
What it actually does:
You attach it to every API request so the API knows who is calling.
fetch("https://api.example.com/profile", {
headers: {
"Authorization": `Bearer ${accessToken}`
}
});
The API verifies:
✔️ signature
✔️ issuer
✔️ audience
✔️ expiry
✔️ scopes (permissions)
✅ ID Token → in memory 🧠✨
What it is: identity snapshot — “who the user is”
Where: in memory
Lifetime: short (~5–15 min)
Used for: UI (display name, avatar, etc.), not for calling APIs
You decode it just to show profile data — not to grant access.
BONUS — Reading the ID Token 🔍
const idToken = "...your.jwt.here...";
const payload = JSON.parse(atob(idToken.split('.')[1]));
console.log(payload);
// object will look something like:
{
name: "Sylwia",
email: "sylwia@example.com",
picture: "https://example.com/avatar.png",
sub: "user-123"
}
⚠️ decode ≠ verify
✅ Refresh Token → HttpOnly cookie 🍪🔒
What it is: the thing that gives you new access tokens
Where: HttpOnly Secure SameSite cookie
Lifetime: long: days/weeks/months
Why: frontend should never read it
What it actually does:
Its only job is to refresh an expired access token.
await fetch("/token/refresh", {
method: "POST",
credentials: "include" // <-- RT cookie auto-sent
});
The frontend doesn’t “see” it — it just benefits from it.
Mental model 🧠📍
| Token | Where | Why |
|---|---|---|
| Access | in memory | short-lived, API calls |
| ID | in memory | UI only |
| Refresh | HttpOnly cookie | unreadable, long-lived |
✅ Mental model diagram
[User]
|
v
[Frontend] -- "I don't know who this is" -->
|
v
[IdP] -- "Okay, here's who they are" --> (ID Token + Access Token + Refresh Token)
|
v
[Frontend] -- stores ID+Access (memory), RT in cookie
|
v
[API] -- "Do you have a valid Access Token?"
Up next — Part 2 🚀
In Part 2 we’ll:
✅ walk the full redirect “dance” 💃
✅ explain PKCE (secure code exchange) 🔐
✅ show how the refresh cookie appears 🍪
✅ cover refresh token rotation ♻️
✅ mention BFF (extra-safe pattern) 🛡️
This content originally appeared on DEV Community and was authored by Sylwia Laskowska
Sylwia Laskowska | Sciencx (2025-10-22T12:33:54+00:00) Auth Explained (Part 1): ID vs Access vs Refresh tokens — 🤔what they ACTUALLY do (and why localStorage is a trap). Retrieved from https://www.scien.cx/2025/10/22/auth-explained-part-1-id-vs-access-vs-refresh-tokens-%f0%9f%a4%94what-they-actually-do-and-why-localstorage-is-a-trap/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.