Skip to main content
CodeOath
← All posts

Auth & Security63 min total · 19 parts

OAuth 2.0 and JWT Explained: What Really Happens When You Click "Sign In"

Part 19 of 19 · ~2 min

Common Mistakes Worth Remembering

  • Storing a token in localStorage on a client-side surface — Tasklight Embed's actual XSS incident. An httpOnly cookie, or a server-side session entirely, is the safer default anywhere a real backend can hold it instead.
  • Treating a valid signature as proof that an action is allowed. All a signature actually confirms is who the claims belong to and that nobody altered them in transit; whether this specific request is permitted is a completely separate question it says nothing about. tasks-service still has to check the granted scope against what the endpoint actually requires.
  • Letting the token itself dictate which algorithm verifies it, instead of hardcoding that choice into the verifier — this exact gap is what made the signature-stripping attack against tasks-service possible in the first place.
  • Skipping aud validation — the precise bug billing-service shipped, letting a tasks-scoped token through an endpoint it was never meant to reach.
  • Treating a JWT as though it could be killed the way a session row gets deleted. By itself it can't be — getting anything close to real-time revocation means either a server-side lookup on every single request, or keeping expiries short and backing them with a refresh token that's genuinely revocable.
  • Mixing up which token goes where — handing an API the identity token, or handing your session logic the API credential. Both are ordinary-looking JWTs at a glance, but only one of the pair is actually trustworthy as a statement of who's logged in.
  • Requesting a broader scope than the feature needs — calendar instead of calendar.readonly would have bought Tasklight nothing beyond a scarier consent screen and a worse blast radius if that token ever leaked.
  • Validating redirect_uri by prefix instead of exact match — Tasklight's own link-shortener open-redirect gap, above.
  • Skipping PKCE on a public client because "there's no client_secret to worry about" — that's precisely the situation PKCE exists for, not a reason to skip it.

Tasklight's own frontend — the login button, the session state, the effects that keep a UI in sync with whether Priya is signed in — is built with the same component patterns covered in React Fundamentals; worth a look for the client-side half of wiring a real button up to a flow like the one in this reference. And since this topic rewards actually tracing a credential through its checks rather than memorizing a list of five steps, the code lab is where to go work through scenarios like these hands-on.