← Home
🏗Crack System Design with DSA AnimatorSystem DesignNEW
🏗 System Design›Networking & Realtime

🔑JWT vs Session / OAuth

Don't confuse token format, session model, and authorization protocol.

📌 Key IdeaSession and JWT are ways to represent authenticated user context after login. OAuth 2.0 is an authorization protocol for delegated access. OIDC adds identity on top of OAuth. Many production systems combine all three (e.g., OAuth login issuing JWT access tokens stored in HttpOnly cookies).
🧩

Problem it solves

  • After login, the server must recognize returning users without re-entering credentials every request.
  • Teams confuse JWT (token format), session (server-side state model), and OAuth (delegation protocol) — leading to wrong security decisions.
  • Microservices need a consistent way to propagate identity and permissions across service boundaries.
📖

Definition

Session auth stores user state server-side; the client holds only a session ID (usually in an HttpOnly cookie). JWT is a signed, self-contained token format carrying claims. OAuth 2.0 is a protocol for delegated authorization (app accessing resources on behalf of a user). OIDC (OpenID Connect) extends OAuth with an ID token for authentication.

✨

Why It Matters

  • Wrong model choice affects revocation, scaling, and security posture.
  • JWT statelessness simplifies horizontal scaling but complicates logout and token invalidation.
  • OAuth enables "Login with Google" without storing user passwords — but scopes and consent matter.
  • Interviewers test whether you understand these are orthogonal concepts that can be combined.
🖼

Visual

🔑 Auth model boundaries
Session:
  server stores session state
  client sends session cookie (HttpOnly)

JWT:
  token carries signed claims
  server verifies signature (stateless)

OAuth 2.0:
  delegated authorization framework
  (often issues JWT access tokens via OIDC)

OIDC:
  identity layer on OAuth
  adds ID token (who the user is)
✅

When to Use

  • Session + cookie for traditional server-rendered web apps needing instant server-side revocation.
  • JWT access token for stateless API auth across microservices (short-lived, signed).
  • Refresh token + access token rotation for SPA/mobile when you need both statelessness and revocable long sessions.
  • OAuth 2.0 / OIDC for third-party login (Google, GitHub) and delegated API access with scoped permissions.
🚫

When NOT to Use

  • Long-lived JWTs (hours/days) without rotation, blacklist, or introspection strategy.
  • Storing JWT in localStorage — XSS can steal it; prefer HttpOnly Secure cookies or memory + refresh flow.
  • Putting sensitive PII or permissions that change frequently inside JWT claims without short TTL.
  • Calling OAuth "authentication" without OIDC ID token — OAuth alone is authorization, not identity proof.
💻

Code Variations

1️⃣ JWT verification (Spring-style sketch)java
Claims claims = Jwts.parser()
    .verifyWith(publicKey)
    .build()
    .parseSignedClaims(token)
    .getPayload();

String userId = claims.getSubject();
if (claims.getExpiration().before(new Date())) {
  throw new TokenExpiredException();
}
Always verify signature, expiration, and issuer (iss) / audience (aud).
2️⃣ Session lookup after cookie parsejava
String sessionId = request.getCookie("SESSION");
Session session = sessionStore.find(sessionId)
    .orElseThrow(UnauthorizedException::new);
User user = session.getUser();
Logout = delete session from store. Instant revocation.
3️⃣ Security checklisttext
JWT:
  - Short access token TTL (5–15 min)
  - Refresh token rotation
  - Never store in localStorage (XSS risk)
  - HttpOnly Secure cookie OR memory-only

Session:
  - HttpOnly + Secure + SameSite cookies
  - CSRF token for state-changing requests
  - Regenerate session ID on login (fixation)

OAuth:
  - Validate redirect URI exactly
  - Use PKCE for public clients
  - Request minimum scopes needed
📊

Session vs JWT vs OAuth vs OIDC

AspectSessionJWTOAuth 2.0OIDC
What it isStateful login context on serverSigned token format (claims + signature)Delegated authorization protocolIdentity layer on OAuth (authn)
State locationServer (session store/Redis)Client carries token; server verifies signatureAuthorization server holds grantsSame + ID token with user claims
RevocationEasy — delete session server-sideHard — need short TTL, blacklist, or introspectionRevoke refresh token / grantRevoke tokens + end session at IdP
ScalingNeeds shared session store for multi-nodeStateless verification — scales horizontallyCentral auth serverCentral identity provider
Best fitWeb app login, admin panelsService-to-service API auth3rd-party API access, scoped delegationSocial login, SSO, federated identity
Common pitfallSession fixation, CSRF (use SameSite)Token theft via XSS, bloated claimsConfusing authn vs authz scopesMisconfigured redirect URIs
🔀

Common Confusions Cleared Up

Authentication vs authorization

Authentication = who are you? Authorization = what can you do? Sessions/JWT/OIDC handle authentication context. OAuth scopes handle authorization (what resources the client may access).

JWT is not OAuth

OAuth is a flow/protocol (authorization code, client credentials, etc.). JWT is one possible token format OAuth can issue. You can have OAuth without JWT (opaque tokens) and JWT without OAuth (custom login issuing JWT).

Stateless JWT vs server session trade-off

JWT wins on horizontal scale (no session lookup). Session wins on instant revocation and smaller client payload. Hybrid: short-lived JWT + refresh token stored server-side or in HttpOnly cookie.

🧪

Variations / Implementations

1) Session cookie (classic web)

Login → server creates session in Redis/DB → sets Set-Cookie: sessionId=...; HttpOnly; Secure; SameSite=Lax. Every request validates session ID against store.

2) JWT bearer token (API / microservices)

Login → server signs JWT with claims (sub, roles, exp) → client sends Authorization: Bearer <token>. Services verify signature with shared/public key — no session lookup.

3) OAuth 2.0 Authorization Code + PKCE (SPA/mobile)

Client redirects to IdP → user consents → auth code returned → client exchanges code for access + refresh tokens. PKCE prevents code interception on public clients.

4) OIDC social login

OAuth flow + ID token (JWT) containing sub, email, name. Your app creates/links local user record from IdP identity — you never see the user's Google password.

⚠️

Common Mistakes / Anti-Patterns

  • Storing JWT in localStorage/sessionStorage (XSS exfiltration).
  • Long-lived access tokens with no revocation path.
  • Putting roles/permissions in JWT that change often — stale until expiry.
  • Using OAuth implicit flow for new apps (deprecated; use auth code + PKCE).
  • Trusting JWT claims without signature verification.
  • Confusing "OAuth login" with building your own password auth.
🎤

Interview Q&A

🔮

Likely Follow-up Questions

  • How would you implement logout across all devices?
  • How do microservices validate tokens without calling auth server every request?
  • What is the BFF (Backend-for-Frontend) pattern and why does it help SPAs?
🧾

Quick Cheat Sheet

SessionState on server; cookie holds session ID only.
JWTSigned claims; verify signature + exp + iss/aud.
OAuthDelegation protocol — not a token format.
OIDCOAuth + ID token for authentication.
RevocationSession = easy; JWT = short TTL + refresh/blacklist.
SPA defaultAuth code + PKCE; tokens in HttpOnly cookie.
🔗

Related Topics