CMD Guide
HomeSystem DesignAuthorization

OAuth vs JWT for Authentication

OAuth 2.0 works by having an authorization server issue a client a scoped, time-limited access token once the resource owner consents, so the client acts on the user's behalf without ever seeing the password; a JWT works by packing claims into a base64url-encoded, cryptographically signed string that anyone holding the verification key can validate on the spot, with no database round-trip.

Put that way, “OAuth vs JWT” is a category error — and the original page half-admitted it by calling them “complementary.” One is a protocol for obtaining a token; the other is one possible format for that token. You do not choose between them; a single request routinely uses both at once. The genuine engineering decision hiding behind the question is: how should a token be validated — as a self-contained artifact, or as a reference the server must look up? That axis is what this page teaches.

What each one actually is

OAuth 2.0 (RFC 6749) is a delegation framework. It defines four roles — resource owner (the user), client (the app), authorization server (issues tokens), and resource server (the API) — plus several grant flows for getting an access token to the client. Crucially, RFC 6749 deliberately says nothing about the token's format: it can be an opaque random string or a JWT. So OAuth does not inherently require server-side token storage — that depends entirely on which token format you pick.

OAuth is not an authentication protocol. An access token answers “may this client call this API?”, not “who is the user?”. Bolting identity onto raw OAuth is the classic mistake. The fix is OpenID Connect (OIDC), a thin layer on top of OAuth 2.0 that adds an ID token — and that ID token is a JWT. So the honest version of this page's title is: use OIDC to authenticate, and the identity it hands you arrives as a JWT.

JWT (RFC 7519) is just a token format: three base64url segments — header.payload.signature — signed with HMAC (HS256) or a public-key algorithm (RS256/ES256). It shows up as OIDC ID tokens, as OAuth access tokens, and as plain application session tokens. Signed is not encrypted: the payload is readable by anyone.

diagram
diagram

Worked example: one login that uses both

Trace “Log in with Google” on a web app via the OAuth 2.0 authorization code flow (the diagram above), with real-ish values:

  1. App redirects the browser to https://accounts.google.com/o/oauth2/v2/auth?client_id=40740.apps.googleusercontent.com&redirect_uri=https://app.example.com/cb&response_type=code&scope=openid%20email&state=xyz123.
  2. Google authenticates the user and shows a consent screen for email.
  3. Browser is redirected back to https://app.example.com/cb?code=4/0AX4Xf...&state=xyz123. The app verifies state matches what it sent, blocking login CSRF.
  4. Server-to-server (the back-channel, so the secret never touches the browser), the app POSTs the code plus its client_secret to /token and receives an access_token (to call the API), an id_token (a JWT — who the user is), and a refresh_token. Modern guidance (OAuth 2.0 Security Best Current Practice, RFC 9700) adds PKCE to this exact flow even for a confidential client like this one — not only for public clients: the app also sends a code_challenge on /authorize and the matching code_verifier here on /token, so an intercepted code cannot be redeemed without it (mechanism traced step by step in the PKCE deep-dive).
  5. The app calls the API with Authorization: Bearer <access_token> and gets the profile back.

Both technologies are at work in this one flow: OAuth ran the delegation dance; the id_token JWT carried the identity. Neither replaced the other.

Anatomy of the JWT it hands you

The id_token is a string like this (jwt.io's canonical HS256 example, line-split for reading):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Base64url-decode each segment:

SegmentDecodedPurpose
Header{"alg":"HS256","typ":"JWT"}which signature algorithm
Payload{"sub":"1234567890","name":"John Doe","iat":1516239022}the claims (real tokens add exp, aud, iss)
SignatureSflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cHMACSHA256(header.payload, secret)

To validate, the server recomputes the signature over the first two segments with its key and compares. If it matches and exp is in the future, the claims are trusted — no database lookup. Flip one byte of the payload and the signature no longer matches, so tampering is caught. But the payload was only signed, not encrypted: base64url-decoding needs no key, so never put secrets in it.

diagram
diagram

The real axis: self-contained vs reference tokens

Here is where the original page's “OAuth is stateful, JWT is stateless” contrast breaks down. Statefulness is a property of the token format, not of OAuth. OAuth can issue either kind:

Both are valid OAuth. So the sloppy claim — “OAuth relies on server-side storage, JWT is stateless” — is really comparing OAuth-with-opaque-tokens against JWTs. That is the category error: it pits a protocol against a format by silently assuming the protocol picks the stateful format.

Pitfalls

When to use which token strategy

The real decision is self-contained (JWT) vs reference (opaque) access tokens — not “OAuth vs JWT.”

Choose self-contained JWTs when requests fan out across many stateless services, per-request latency matters, and you can tolerate a revocation window of a few minutes. You gain: no lookup, trivial horizontal scaling, no shared session store. It costs: no instant revocation, larger tokens sent on every request (headers grow), key-rotation machinery, and claims that stay stale until expiry.

Prefer opaque reference tokens (validated via introspection) when instant revocation is a hard requirement (banking, admin consoles), tokens must stay small, or scopes may change mid-session. You gain: kill-a-session-now, tiny tokens, central control. It costs: a network/DB lookup on every request — latency plus a hot dependency on the auth server — which you then paper over with short-lived caching, landing you back near JWT's staleness trade-off.

Common middle ground: short-lived JWT access tokens (5–15 min) plus a long-lived opaque refresh token that is checked against server state at refresh time. Fast stateless validation on the hot path; a real revocation point on the cold path.

Takeaways


Sources: OAuth 2.0 (RFC 6749) and Bearer Token Usage (RFC 6750); JSON Web Token (RFC 7519); OAuth 2.0 Token Introspection (RFC 7662); OpenID Connect Core 1.0; the OWASP JSON Web Token Cheat Sheet; and jwt.io's canonical HS256 example token. Re-authored/deepened for this guide.

🤖 Don't fully get this? Learn it with Claude

Stuck on OAuth vs JWT for Authentication? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **OAuth vs JWT for Authentication** (System Design) and want to truly understand it. Explain OAuth vs JWT for Authentication from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **OAuth vs JWT for Authentication** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **OAuth vs JWT for Authentication** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **OAuth vs JWT for Authentication** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes