JWT vs Server Sessions: The Ultimate Guide
"We use JWT because it is modern." This is a bad reason.
Server Sessions (Stateful)
- User logs in.
- Server creates a Session ID (random string), stores it in Redis/DB.
- Sends ID as
Set-Cookie(HttpOnly). - Revocation: Easy! Just delete it from Redis. User is logged out instantly.
JWT (Stateless)
- User logs in.
- Server signs a JSON token with a secret.
- Sends token to client.
- Server forgets it!
- Client sends token back. Server verifies signature.
The Problem: You cannot revoke a JWT. If it is stolen, the attacker has access until it expires. Fix: Short expiry (15 min) + Refresh Tokens (stored in DB). Wait... if you store Refresh Token in DB, aren't you just doing Sessions with extra steps?
When to use What?
Use Sessions (Cookies) if:
- You are a standard Web App (Next.js, Rails, Django).
- Immediate revocation is important (Billing, Admin panels).
Use JWT if:
- You have Microservices (Auth service issues token, others verify).
- Mobile App is the client (Cookies are hard on mobile).
Best Practice
For a typical Next.js app: Use NextAuth.js. It handles sessions (via database) or JWTs automatically. Don't roll your own crypto.