Home
About
Blog
Skills
Projects
Contact
Home
About
Blog
Skills
Projects
Contact
Back to Matrix
Security 7/25/2026 7 min read

Securing Your APIs: JWT vs. Sessions

Securing Your APIs: JWT vs. Sessions
#API#Auth#Security

The choice is not really about tokens versus cookies. It is about where the source of truth for a login lives: in your data store, or in a signed string you handed to the client.

How Sessions Work

The server creates a record, gives the client an opaque identifier in a cookie, and looks the record up on every request. Revocation is a delete. Permission changes take effect immediately because the record is read fresh each time.

The cost is a lookup per request and shared state between instances. In practice a Redis lookup adds well under a millisecond, which is far less than most applications spend on their own database queries. The scaling objection is largely folklore.

How JWTs Work

The server signs a payload containing claims. Anyone holding the public key can verify it without asking the issuer. That is genuinely valuable when a request crosses trust boundaries: a gateway validating before routing, independent services accepting a caller's identity, a third party checking a token you issued.

The cost is that you cannot un-issue one. Fire someone, and their token keeps working until it expires. The standard fix is a revocation list, which reintroduces the central lookup you adopted JWTs to avoid.

The Hybrid Almost Everyone Should Use

Short-lived access token plus long-lived, revocable, rotating refresh token. You get stateless verification on the hot path and real revocation on a bounded delay.

```js
const ACCESS_TTL = '10m';

function issueAccessToken(user) { return jwt.sign( { sub: user.id, roles: user.roles, ver: user.tokenVersion }, PRIVATE_KEY, { algorithm: 'RS256', expiresIn: ACCESS_TTL, audience: 'api', issuer: 'auth.example.com' } ); }

function verify(token) { return jwt.verify(token, PUBLIC_KEY, { algorithms: ['RS256'], // never trust the header's alg audience: 'api', issuer: 'auth.example.com', }); } ```

The tokenVersion claim is the cheap emergency brake. Increment it on the user record during a password reset or a compromise, and every outstanding token for that user is invalid on next verification.

Mistakes That Cause Real Breaches

  • Trusting the alg header. Always pin the algorithm on the verifying side. This is how signature-stripping attacks succeed.
  • Storing tokens in localStorage. Any XSS becomes full account takeover. Use httpOnly, Secure, SameSite cookies and pair them with CSRF protection.
  • Skipping aud and iss checks. A valid token for a different service should not open yours.
  • Multi-hour access tokens. That window is exactly how long a stolen token stays useful.
  • Putting sensitive data in the payload. A JWT is signed, not encrypted. Anyone can read it.

Choosing Quickly

Single backend serving your own web app: sessions. Public API with many independent consumers or a service mesh: short-lived JWTs with rotating refresh tokens. When in doubt, pick sessions, because revocation you get for free is worth more than a lookup you will never notice.

Enjoyed this article?

Share it with your network and join the conversation.