Authentication Explained: Sessions, JWTs, and OAuth — What's Actually Happening
Three mechanisms, each solving a genuinely different piece of 'how does the server know who you are' — and where each one's security tradeoff lives.
"Authentication" gets treated as one concept, but session-based auth, JWTs, and OAuth are solving three genuinely different problems, and knowing which is which is what actually determines the right choice for a given project.
Session-based authentication
On login, the server creates a session record (in memory, or more durably in a database like Redis) and sends the client a session ID in an `HttpOnly` cookie — the exact mechanism from the cookies-vs-localStorage post earlier in this blog. Every subsequent request includes that cookie automatically; the server looks up the session ID to know who's asking. The server holds the actual state — revoking a session (forcing a logout) is a simple, immediate database delete.
JWTs (JSON Web Tokens)
header.payload.signature
// The payload might contain: { "userId": 42, "exp": 1234567890 }
// The signature proves the server issued it and it hasn't been tampered
// with — but the payload itself is only base64-encoded, not encrypted;
// anyone can decode and read it, they just can't forge a valid signature.A JWT is a self-contained, signed token — the server doesn't need to look anything up in a database to verify it; it just checks the signature. That statelessness is genuinely useful for a distributed system (multiple backend servers, no shared session store needed) — and it's also the real cost: a JWT can't be instantly revoked the way a session can, since the server isn't keeping a record of which tokens are still valid; it just trusts the signature and the expiry until that expiry passes.
OAuth
A different problem entirely: not "how does the server remember who you are between requests," but "how do you let a user grant a third-party app limited access to their account on ANOTHER service," without ever handing that third-party app your actual password. "Sign in with Google" is OAuth: your app never sees the user's Google password — Google authenticates them directly and hands your app a token proving that authentication happened, scoped to only what you asked for.
The practical takeaway
Session-based auth is the sensible default for a typical single-backend web app — it's simpler, and instant revocation is a real security property worth having. JWTs earn their place specifically when statelessness across multiple services is a genuine requirement. OAuth is for third-party delegated access, not a replacement for either of the other two — a real app frequently uses OAuth for "sign in with Google" and then issues its own session or JWT afterward for its own subsequent requests.