Menu
Course/Security & Identity Patterns/Token-Based Auth (JWT & OAuth2)

Token-Based Auth (JWT & OAuth2)

Architectural view of JWT and OAuth2: token issuance, validation, refresh flows, token storage, and securing microservice-to-microservice communication.

15 min readHigh interview weight

Token-Based Authentication at the Architecture Level

In session-based auth, the server stores session state and the client holds only a session ID cookie. In token-based auth, the server is stateless: all necessary state is embedded in a signed token that the client presents with each request. This trade-off is fundamental to scaling distributed systems — no centralized session store means any server can validate any request independently.

JWT Structure

A JSON Web Token (JWT) is a base64url-encoded, dot-separated string: `header.payload.signature`. The header specifies the algorithm (`alg`), the payload contains claims (the data), and the signature proves the token was issued by a trusted party and has not been tampered with.

text
// JWT Header (base64url decoded)
{
  "alg": "RS256",   // Algorithm: RSA + SHA-256 (asymmetric, preferred)
  "typ": "JWT",
  "kid": "key-2024-01"  // Key ID — used to look up the public key in JWKS
}

// JWT Payload (base64url decoded)
{
  "iss": "https://auth.example.com",   // Issuer
  "sub": "user_abc123",                // Subject (user ID)
  "aud": "https://api.example.com",    // Audience (who should accept this token)
  "iat": 1700000000,                   // Issued at (Unix timestamp)
  "exp": 1700003600,                   // Expires at (iat + 1 hour)
  "roles": ["read:orders", "write:orders"],
  "tenant_id": "acme-corp"
}

// Signature (server-side verification pseudocode)
signature = RS256(
  base64url(header) + "." + base64url(payload),
  privateKey  // Only the auth server holds this
)

// Full JWT (sent to client and presented on every request)
eyJhbGci...  .  eyJpc3Mi...  .  signature_bytes_base64url
⚠️

JWT Pitfall: 'alg: none' Attack

A notorious JWT vulnerability allows attackers to set `"alg": "none"` in the header and remove the signature entirely. Vulnerable libraries accept this as valid if they don't enforce algorithm allowlisting. Always explicitly specify allowed algorithms in your JWT validation library and never accept `alg: none`.

OAuth2 Grant Types — Architectural View

Grant TypeUse CaseToken ReturnedNotes
Authorization Code + PKCEWeb app, mobile, SPA user loginAccess + ID + Refresh tokensPreferred for all user-facing flows
Client CredentialsMachine-to-machine (M2M), service accountsAccess token onlyNo user involved; client authenticates with client_secret
Refresh TokenSilently renewing short-lived access tokensNew access token (+ new refresh token)Rotate refresh tokens on each use
Device CodeInput-constrained devices (TV, CLI)Access + Refresh tokensPolling-based; user approves on secondary device
Implicit (deprecated)Legacy SPAsAccess token directlyAvoid — tokens exposed in URL fragment

Access Token + Refresh Token Flow

Loading diagram...
Short-lived access tokens + rotated refresh tokens: the standard OAuth2 token lifecycle.

Token Storage: Where to Keep Tokens

Storage LocationXSS RiskCSRF RiskRecommendation
localStorage / sessionStorageHigh — JS can read itNoneDo NOT store sensitive tokens here
In-memory (JS variable)Low — not persistentNoneOK for access tokens in SPA; lost on refresh
HttpOnly, Secure CookieNone — JS cannot readPresent (mitigate with SameSite)Best for refresh tokens; use SameSite=Lax or Strict
Backend-for-Frontend (BFF)None — browser holds only session cookieMitigated at BFF layerGold standard for SPA security

Service-to-Service Auth (M2M)

In microservice architectures, services must authenticate to each other, not just to users. The OAuth2 Client Credentials grant is the standard pattern: each service has a `client_id` and `client_secret` (or a certificate) and exchanges these for an access token from the auth server. The calling service attaches this token to outgoing requests; receiving services validate it the same way they validate user tokens.

typescript
// M2M Client Credentials flow — pseudocode for a microservice
async function getServiceToken(): Promise<string> {
  const response = await fetch("https://auth.example.com/oauth/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "client_credentials",
      client_id: process.env.SERVICE_CLIENT_ID,
      client_secret: process.env.SERVICE_CLIENT_SECRET,
      scope: "orders:read inventory:write",
    }),
  });
  const { access_token, expires_in } = await response.json();
  // Cache the token until (expires_in - buffer) seconds
  cacheToken(access_token, expires_in - 60);
  return access_token;
}

// Call downstream service with service token
async function getInventory(itemId: string) {
  const token = await getCachedOrFetchToken();
  return fetch(`https://inventory-service/items/${itemId}`, {
    headers: { Authorization: `Bearer ${token}` },
  });
}
💡

Token Introspection vs Offline Validation

JWT validation is offline (just cryptographic verification using cached public keys) — fast and scalable. Token introspection calls the auth server's `/introspect` endpoint to check if a token is still active (catching revoked tokens in real-time) — slower but necessary for high-security scenarios. A common hybrid: validate JWT offline for every request, and periodically call introspection for long-running sessions or when a user reports a compromised account.

💡

Interview Tip

In system design interviews, when discussing authentication, explicitly address three scenarios: (1) browser-to-API (OIDC + access token in memory or BFF pattern), (2) mobile-to-API (Authorization Code + PKCE), (3) service-to-service (Client Credentials with cached tokens). Mentioning token rotation for refresh tokens and the 'alg: none' vulnerability shows senior-level security awareness. Also mention that access tokens should be short-lived (15 min) to limit the blast radius of a leaked token, and that refresh token rotation + revocation lists catch stolen refresh tokens.

📝

Knowledge Check

5 questions

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

Ask about this lesson

Ask anything about Token-Based Auth (JWT & OAuth2)