Skip to content

Test your website now

Free, no card. We read only public pages.

Run free audit →

Security

What is a JWT, and how does JWT authentication work?

A JWT is a signed token carrying claims about a user. How it works, how to verify one, where to store it, and common mistakes.

A JWT, JSON Web Token, carries claims about a user or other subject. The common signed form has a header, payload and signature. Servers verify its signature, issuer, audience and expiry before accepting it. Its payload is readable, so keep secrets out. JWT also supports encrypted tokens; signing alone does not provide confidentiality.

Published · Last updated

By Michal Měřínský. Audit methodology.

What a JWT is

A commonly used signed JWT has three base64url-encoded parts joined by dots. JWT also supports encrypted JWE tokens; this guide describes the signed form:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJleHAiOjE3OTk5OTk5OTl9.signature
  • Header: the signing algorithm, such as HS256 or RS256.
  • Payload: claims, such as sub for the user ID, exp for the expiry time and iat for when it was issued.
  • Signature: proves the header and payload were created by someone holding the key and not changed since.

How JWT authentication works

  • The user logs in. The server checks the password and issues a short-lived access token, often with a longer-lived refresh token.
  • The client sends the access token with each request, usually in an Authorization: Bearer header.
  • The server verifies the signature and expiry, then trusts the claims without a database lookup.
  • When the access token expires, the client uses the refresh token to get a new one. Services such as Supabase Auth, Auth0 and Firebase issue JWTs this way, which is why vibe-coded apps meet them constantly.

Verifying a token correctly

  • Verify the signature with the expected key and an explicit list of allowed algorithms. Never trust the alg value the token claims for itself.
  • Reject tokens without a valid exp, and check iss and aud when your provider sets them.
  • Use a maintained library. Hand-written JWT verification is a common source of serious vulnerabilities.

Decoding is not verifying. Reading the payload of a JWT, which anyone can do, proves nothing about who created it.

Where to store it in the browser

  • localStorage is simple, but any script running on your page, including injected script from an XSS bug, can read it.
  • An HttpOnly, Secure cookie cannot be read by JavaScript, which removes that risk, but cookies are sent automatically, so you need SameSite and CSRF protection. There is no perfect option. Short-lived access tokens limit the damage either way, and a strong Content Security Policy reduces the XSS risk.

Common mistakes

  • Putting secrets or personal data in the payload, which is readable by anyone.
  • Very long expiry times with no way to revoke tokens.
  • Weak or leaked HMAC secrets, such as a default value from a tutorial.
  • Accepting tokens with the none algorithm, or confusing public and secret keys between algorithms.
  • Trusting role claims set by the client instead of the server.

What a scan can and cannot tell you

WebAuditOS checks observed Set-Cookie response headers for Secure and SameSite, and uses a session-like name heuristic for HttpOnly, excluding csrf and xsrf names, and checks for a Content Security Policy, which limits the damage of script injection.

It cannot see tokens stored in localStorage after login, test whether your API verifies signatures, or check expiry and revocation. Those need a review of your authentication code.

A scan sees what anonymous visitors receive. Most JWT problems live in authenticated requests a public scan never makes.

Short answers

Is a JWT encrypted? Usually not. It is signed. Use JWE if you need encryption.

How long should a JWT last? Access tokens minutes to an hour, with refresh tokens for longer sessions.

Can you log a user out with JWTs? Not instantly without extra work, such as short expiries or a revocation list.

JWT or session cookie? Both work. Sessions are simpler for a single web app. JWTs suit APIs and multiple services.

In the product

The checks this maps to

Every check named here runs on every scan, on every plan - what a plan changes is how many pages are crawled, how long the history is kept and what you can do with the result. These are the ids the findings carry, so you can match a line in a report to the explanation above.