For a browser-based web app with one backend, a server-side session identifier in a protected cookie is usually the simpler and safer choice. JWTs suit credentials that several independent services must verify without calling a central store. The deciding factors are revocation, who verifies, and where the token is kept.
What is the difference?
A session cookie holds an opaque random identifier. The server looks it up in a store and finds the user and state. Revoking is deleting the record.
A JSON Web Token (RFC 7519) is a compact, URL-safe way to carry claims between parties, signed or encrypted. The recipient can verify it without a lookup. The price is that the token remains valid until it expires unless you add a deny list, which brings back the lookup.
Note that they are not exclusive. A JWT can be stored in a cookie, and a session cookie can be backed by signed data.
What does the security guidance say about sessions?
OWASP's session management cheat sheet gives concrete rules. Session identifiers need at least 64 bits of entropy. The HttpOnly attribute stops scripts reading the cookie, which it calls mandatory protection against session theft through XSS. Cookies should also carry the Secure attribute so they are not sent in the clear, and the guidance covers SameSite and expiry too.
What goes wrong with JWTs?
RFC 8725 exists because JWT deployments went wrong repeatedly. It updates RFC 7519 with best current practices: validate the algorithm you expect rather than trusting the token header, verify signatures and claims such as issuer, audience and expiry, and avoid putting sensitive data in an unencrypted payload.
A constructed example: a team stores a one-hour JWT in browser local storage. A third-party script with an XSS flaw reads it and the attacker has an hour of access, and logout does not help because the server has no way to cancel the token. The same app with an HttpOnly session cookie and a server-side record can end the session instantly.
When does each fit?
Sessions fit a single web application or a small set of services sharing a store, where instant logout and revocation matter, such as admin consoles and finance tools.
JWTs fit service-to-service calls, delegated access with short lifetimes, and cases where several parties must verify identity without a shared database. Keep lifetimes short and pair them with refresh handling you can revoke.
What about refresh tokens and logout?
Many JWT designs use a short-lived access token and a longer-lived refresh token. The refresh token is the real session: it should be stored server-side or in an HttpOnly cookie, rotated on use and revocable. If you cannot revoke it, you have built a long-lived bearer credential with extra steps.
Logout deserves a test, not an assumption. After the user clicks it, replay the old token or cookie from another client. If the request still succeeds, logout only cleared the browser. For JWTs this usually means keeping a small deny list or a per-user token version that the verifier checks, which is a deliberate trade against statelessness.
How to check or apply this
- List every service that must verify the credential. If it is one, prefer sessions.
- Decide how fast you must revoke access after a password change or incident.
- For cookies, set HttpOnly, Secure and SameSite, and use framework-generated identifiers.
- For JWTs, pin the allowed algorithm, validate issuer, audience and expiry, and keep lifetimes in minutes.
- Do not store bearer tokens in places scripts can read.
- Rotate session identifiers at login and privilege change.
- Test logout: after it, the old credential must fail.
Safeguard's dependency scanning can flag vulnerable JWT and session libraries in your stack, which is a common source of real incidents.
Quick check
Are JWTs more secure than cookies?
Not inherently. Security depends on storage, validation and revocation. Many JWT failures come from implementation mistakes.
Can I put a JWT in a cookie?
Yes, with HttpOnly, Secure and SameSite set. That removes script access but not the revocation problem.
Sources
- RFC 7519, JSON Web Token
- RFC 8725, JSON Web Token Best Current Practices
- OWASP Session Management Cheat Sheet
Last reviewed: 18 October 2026.