12. Authentication Fundamentals (Sessions vs JWT)
Authentication Fundamentals (Sessions vs JWT)
Authentication is the process of verifying who you are. When you type your email and password into a login form, the server is performing authentication — confirming that you are who you claim to be. After that moment, every subsequent request you make needs to prove that you already authenticated, without logging in again on every page load.
This "prove who you are on every request" problem is what Sessions and JWTs solve differently. Understanding both — and when to use each — is a fundamental backend competency.
The Core Problem: HTTP is Stateless
HTTP is a stateless protocol. Each request is completely independent. When your browser sends a request to GET /dashboard, the server has no memory of the previous request. It doesn't know you just successfully logged in 2 seconds ago.
To stay "logged in," every request after login must include a credential that the server can verify. The two main approaches to carrying that credential are Sessions (server-side) and JWT tokens (client-side).
Session-Based Authentication
In the session model, after a successful login, the server creates a session record in its database (or Redis) and sends back a short, random session ID in a cookie. On every subsequent request, the browser automatically sends the cookie. The server looks up the session ID, finds the associated user data, and knows who you are.
/login + credentialspassword correctsession in DB/RedisSet-Cookie: sid=abc123automatically include cookieAdvantages of Sessions: Easy to invalidate (just delete the session from Redis). No sensitive data travels in the cookie — just an opaque ID. The server always has full control.
Disadvantages: Requires shared state storage (Redis) that all servers must access. Doesn't scale naturally to mobile apps or microservices.
JWT — JSON Web Token Authentication
JWT (JSON Web Token) takes a completely different approach: instead of storing session data on the server, you encode the user's identity inside the token itself and send the entire token to the client. The token is cryptographically signed, so the server can verify it was issued by itself without any database lookup.
The server never stores anything. To verify a JWT, it just re-computes the signature using its secret key and checks if it matches. If someone tampers with the payload (changes role from "user" to "admin"), the signature won't match — the token is rejected.
Refresh Tokens — Keeping Users Logged In Safely
Access tokens should have short lifespans (15 minutes to 1 hour) to minimize risk if stolen. But you don't want users to re-login every 15 minutes. The solution is a Refresh Token system: a long-lived token (stored in an httpOnly cookie) that is used only to get new short-lived access tokens.
Short-lived (15 minutes). Sent in the Authorization header with every API request. If stolen, expires soon.
Long-lived (30 days). Stored in an httpOnly cookie. Never sent to API routes — only to /auth/refresh.
Sessions vs JWT — When to Use Each
This is one of the most debated topics in backend architecture. Here is the practical breakdown:
- Use Sessions when: Building a traditional web app where the backend and frontend are on the same domain (or subdomain). You need the ability to immediately invalidate a user's session (e.g., when they report their account as compromised). You have Redis available.
- Use JWT when: Building a REST API consumed by mobile apps or third-party clients. Building microservices where stateless authentication is important. Your backend and frontend are on different domains (CORS makes cookies complicated).
- In practice: Most production systems use a hybrid — JWTs for API authentication, combined with Redis-stored refresh tokens so you can still invalidate sessions when needed.
Knowledge Check
Ready to test your understanding of 12. Authentication Fundamentals (Sessions vs JWT)?