Menu
Course/Security & Auth/OAuth 2.0 & JWT

OAuth 2.0 & JWT

OAuth2 grant types, JWT structure and validation, access tokens vs refresh tokens, token storage, and common security pitfalls.

18 min readHigh interview weight

Why Authentication Is Hard at Scale

Authentication — confirming who a user is — seems simple in a monolith with a single session store. Once you have microservices, mobile clients, third-party integrations, and millions of users, the problem explodes in complexity. You need a protocol that is stateless (so any server can validate a token without calling a central store), delegatable (so a user can grant limited access to a third-party app), and revocable (so stolen credentials can be invalidated quickly). OAuth 2.0 and JWTs together address these requirements, which is why they appear in nearly every system design interview involving user data.

OAuth 2.0: The Protocol

OAuth 2.0 is an authorization framework, not an authentication protocol. It allows a Resource Owner (user) to grant a Client (your app) limited access to resources stored on a Resource Server (e.g., Google Drive) without sharing credentials. An Authorization Server (e.g., Auth0, Google Identity) issues tokens. OpenID Connect (OIDC) sits on top of OAuth 2.0 to add authentication — it introduces the `id_token` (a JWT describing the user) on top of the access token.

Grant TypeWho Uses ItHas User InteractionRecommended
Authorization Code + PKCEWeb apps, SPAs, MobileYesYes — current best practice
Client CredentialsServer-to-server (M2M)NoYes — for backend services
Device CodeSmart TVs, CLIs, IoTYes (secondary device)Yes — for constrained devices
ImplicitSPAs (legacy)YesNo — deprecated, token exposed in URL
Resource Owner PasswordFirst-party trusted clientsNo (password sent)No — avoid, defeats OAuth purpose

Authorization Code Flow with PKCE

Loading diagram...
OAuth 2.0 Authorization Code Flow with PKCE — the recommended flow for all user-facing apps

JWT: Structure and Validation

A JSON Web Token (JWT) is a compact, URL-safe token format that encodes claims as a signed JSON object. It has three Base64URL-encoded segments separated by dots: `header.payload.signature`. The header specifies the signing algorithm (`alg`). The payload contains claims. The signature proves the token was issued by a trusted party and was not tampered with.

json
// Header (decoded)
{
  "alg": "RS256",   // RSA signature with SHA-256
  "typ": "JWT",
  "kid": "key-id-1" // Key ID for rotation
}

// Payload (decoded)
{
  "iss": "https://auth.example.com",  // Issuer
  "sub": "user_12345",                // Subject (user ID)
  "aud": "api.example.com",           // Audience
  "exp": 1740000000,                  // Expiry (Unix timestamp)
  "iat": 1739996400,                  // Issued at
  "jti": "unique-token-id",           // JWT ID (for blacklisting)
  "roles": ["viewer", "commenter"],   // Custom claims
  "plan": "pro"
}

// Signature = RS256(base64url(header) + "." + base64url(payload), privateKey)
⚠️

JWTs Are Signed, Not Encrypted

The payload of a standard JWT (JWS — JSON Web Signature) is only Base64URL-encoded, NOT encrypted. Anyone who obtains the token can decode and read the claims. Never store sensitive data (passwords, PII, payment info) in a JWT payload. For confidential payloads, use JWE (JSON Web Encryption) instead.

Validation Checklist

  1. Verify signature using the public key (for RS256) or shared secret (for HS256). Reject if invalid.
  2. Check `alg` header — reject `alg: none` or unexpected algorithms (algorithm confusion attacks).
  3. Validate `exp` claim — reject if token is expired.
  4. Validate `iss` (issuer) matches your expected authorization server.
  5. Validate `aud` (audience) contains your service's identifier.
  6. Optionally check `jti` against a token blacklist if revocation is needed.

Access Tokens vs Refresh Tokens

PropertyAccess TokenRefresh Token
LifetimeShort (5–60 minutes)Long (days to months)
Sent toResource Server (APIs)Authorization Server only
StorageMemory or HttpOnly cookieSecure HttpOnly cookie
RevocableNot easily (stateless)Yes — stored in Auth Server DB
PurposeProves authorization for API callsObtains new access tokens
If stolenAttacker has limited windowAttacker can generate tokens indefinitely

The standard pattern is: issue a short-lived access token (15–60 minutes) for API access and a long-lived refresh token (7–30 days) stored in an HttpOnly cookie. When the access token expires, the client silently exchanges the refresh token for a new pair. This limits exposure if an access token is stolen while keeping users logged in without re-authentication.

Token Storage Security

Storage LocationXSS RiskCSRF RiskRecommendation
localStorage / sessionStorageHIGH — JS can read itLowAvoid for sensitive tokens
In-memory (JS variable)Medium — lost on refreshLowGood for short-lived access tokens
HttpOnly CookieLow — JS cannot read itHIGH — sent automaticallyUse with CSRF tokens or SameSite=Strict
HttpOnly + SameSite=Strict CookieLowLowBest practice for refresh tokens
💡

Interview Tip

In interviews, when asked about auth, lead with the threat model. Ask: 'Is this a mobile app, SPA, or server-rendered app?' SPAs should use Authorization Code + PKCE, store refresh tokens in HttpOnly cookies, and access tokens in memory. Mention the XSS vs CSRF trade-off with cookie storage — showing you understand both attack vectors impresses interviewers.

Common Pitfalls and Attacks

  • JWT Algorithm Confusion: Attacker changes `alg` from `RS256` to `HS256` and signs with the public key (which they have). Always pin the expected algorithm server-side.
  • Open Redirect in Redirect URI: OAuth redirects to attacker-controlled URL if `redirect_uri` is not strictly validated. Always whitelist exact redirect URIs.
  • CSRF on Authorization Endpoint: Without a `state` parameter, attacker can initiate OAuth flow on victim's behalf. Always validate the `state` parameter to prevent CSRF.
  • Token Leakage via Referer Header: Access tokens in URL query params (like Implicit flow) leak through `Referer` headers. Never put tokens in URLs.
  • Refresh Token Theft: A compromised refresh token grants indefinite access. Use refresh token rotation (issue new refresh token on each use, invalidate old one) and detect reuse as a breach signal.
💡

Use an Identity Provider in Production

Building OAuth 2.0 from scratch is error-prone and risky. Use a managed identity provider: Auth0, Okta, AWS Cognito, Google Identity Platform, or Keycloak (self-hosted). They handle token storage, refresh rotation, MFA, social login, and compliance (SOC2, GDPR) out of the box. In interviews, mention this and explain what your custom solution would need to replicate.

📝

Knowledge Check

5 questions

Test your understanding of this lesson. Score 70% or higher to complete.

Ask about this lesson

Ask anything about OAuth 2.0 & JWT