Web session architecture

Session Cookies vs JWTs

Compare server sessions and JSON Web Tokens by browser security, revocation, scale, claims, and operational needs.

How this page is maintained

Written for learners, checked against the sources below, and reviewed every quarter. Last reviewed July 27, 2026.

Short answer

A session cookie usually stores an opaque identifier while trusted server storage holds session state. A JWT is a signed token whose claims can be verified without a central lookup, although systems often still need state for revocation and account changes. Neither is automatically safer or more scalable. Browser threat models, token audience, lifetime, storage, rotation, and service boundaries determine the fit.

Who this is for: Web and API developers choosing how an application will preserve authenticated state after a user signs in.

  • Use protected browser cookies for browser credentials instead of exposing bearer tokens to ordinary page scripts.
  • Keep claims minimal, scoped, short-lived, and validated for issuer, audience, time, and approved algorithm.
  • Choose architecture from revocation and service needs, not from the assumption that JWT means stateless.

Opaque sessions centralize current state

With a server session, the browser sends a random opaque identifier and the server retrieves the associated principal and state. Logout, suspension, privilege change, and device revocation can take effect by deleting or changing that record. The identifier must be unpredictable, rotated at sign-in, protected in transit, and expired after an appropriate idle or absolute duration.

Central state adds a lookup and an availability dependency. A distributed application may use a shared session store or route consistently, each with failure and cost tradeoffs. The cookie should use Secure, HttpOnly, an appropriate SameSite value, narrow Path and Domain scope, and a name that prevents accidental shadowing where applicable.

JWTs carry verifiable claims

A JWT commonly contains issuer, subject, audience, timestamps, and scoped claims protected by a signature. A recipient verifies the signature and required claims before trusting it. Encoding is not encryption, so claims are readable unless a separate encryption design is used. Never place passwords, secrets, or unnecessary personal data inside a signed token.

Local verification can help services accept tokens from a trusted issuer without sharing session storage. It also means a stolen token can remain usable until expiration unless the architecture checks revocation or rotates credentials. Key distribution, algorithm selection, clock handling, audience separation, and issuer validation become critical operational responsibilities.

Browser storage changes the risk

A bearer token available to JavaScript can be stolen by injected script. An HttpOnly cookie prevents script from reading the credential, though the browser still sends it automatically, so cross-site request protections matter. SameSite helps but should be combined with method discipline, origin checks, or anti-CSRF tokens where the application threat model requires them.

Do not move a JWT into local storage merely to avoid CSRF and call the system secure. That trade exposes the bearer token to script compromise and complicates rotation. A JWT can itself be transported in a protected cookie. Token format and browser transport are separate design choices that should be evaluated independently.

Choose from lifecycle requirements

For a conventional server-rendered web application, an opaque session cookie is often the simpler starting point. For service-to-service delegation or independently operated APIs, short-lived access tokens with specific audiences may fit better. Some systems use a protected browser session at the edge and exchange scoped internal tokens behind it.

Document issuance, renewal, expiration, logout, revocation, account recovery, key rotation, and incident response before choosing. Test stolen-token scenarios and privilege changes. Review current platform guidance because cookie behavior, identity libraries, and deployment topology change. Avoid custom token cryptography; use maintained implementations and secure platform facilities.

Choose credentials for a team dashboard

A browser dashboard calls one application backend, which then calls two internal services on the user's behalf.

  1. Use an opaque, rotated session identifier in a Secure, HttpOnly, narrowly scoped cookie between browser and application backend.
  2. Keep current membership and revocation state in the server session rather than embedding long-lived roles in the browser credential.
  3. Have the backend obtain short-lived, audience-specific internal credentials only when a service call requires delegated identity.
  4. Validate issuer, audience, expiration, and scope at each service, and never forward one broad token to unrelated recipients.
  5. Test logout, removed membership, expired internal credentials, key rotation, CSRF defenses, and a stolen browser session.
Result: The browser gets a simple revocable session, while internal services receive narrow credentials without exposing reusable service tokens to page scripts.

Credential architecture checklist

Compare candidate designs against the complete credential lifecycle.

  • Transport and storage: browser cookie flags, script access, mobile secure storage, TLS, and log redaction.
  • Trust: issuer, audience, subject, signature keys, approved algorithms, and service boundaries.
  • Lifecycle: creation, rotation, idle and absolute expiry, renewal, logout, revocation, and recovery.
  • Authority: claim freshness, server-side policy, tenant scope, delegation, and privilege-change timing.
  • Operations: store availability, key rotation, incident containment, metrics, tests, and support tooling.

Common mistakes

  • Calling JWT payloads secret even though ordinary signed tokens are only encoded and can be read.
  • Putting a long-lived bearer token in browser local storage without evaluating script compromise.
  • Embedding permanent roles in tokens and ignoring revocation when membership changes.

Try one

A browser-only product proposes a seven-day JWT in local storage so its API can remain stateless. Evaluate the proposal and offer a safer design.

A strong evaluation identifies bearer theft through injected script, stale authorization for seven days, weak logout, and the false assumption that no state is ever needed. A safer default is a short, opaque session identifier in a Secure and HttpOnly cookie with CSRF controls and server-side revocation. Short-lived scoped JWTs may still serve internal API boundaries when their lifecycle is justified.

Sources

Learn this with a tutor

Tell LearnLive what you already know and what you need to do with session cookies versus jwts.

Build this course