← Learn

Definition

What is a JWT (JSON Web Token)?

We scanned nearly 2,000 AI-built apps and 1 in 8 shipped a high-severity flaw. Want to check yours?Scan free →

A JSON Web Token (JWT) is a compact, signed token that a server issues to prove who a user is. It carries claims, like a user id, and a cryptographic signature. The server can trust the claims because it can verify the signature. The most common and dangerous mistake is reading a JWT's contents without verifying that signature.

How it works

A JWT has three parts: a header, a payload of claims, and a signature. The payload is only base64-encoded, not encrypted, so anyone can read it. The signature is what makes it trustworthy, because only the server with the secret can produce a valid one.

Decode vs verify

Decoding a JWT just reads the payload and checks nothing. Verifying checks the signature against your secret. If your code decodes without verifying, an attacker can hand you a token with any claims they like, for example an admin flag, and you will believe it. Always verify.

What this means for AI-generated code

AI tools sometimes use a decode function instead of a verify function, because the two have nearly identical names and both return the payload. The code works for legitimate tokens, so the missing signature check is invisible until someone forges a token.

Common questions

What is the difference between jwt.decode() and jwt.verify()?

jwt.decode() reads the payload without checking the signature — it accepts any token, including forged ones, and returns the claims. jwt.verify() checks the signature against your secret and only returns the payload if the signature is valid. You should always use verify(), never decode(), when making access decisions.

Can I store a JWT in localStorage?

You can, but a session cookie with HttpOnly and Secure flags is safer. A JWT in localStorage is readable by any JavaScript on your page, so an XSS vulnerability can steal it. An HttpOnly cookie is never accessible to JavaScript, so the same XSS cannot steal it — the attacker can make requests with it but cannot read the token value.

How long should a JWT last?

Short-lived access tokens (15 minutes to 1 hour) with a longer-lived refresh token is the standard pattern. A short expiry limits the window if a token is stolen. The refresh token, which is used to get a new access token, should be stored in an HttpOnly cookie and rotated on each use so a stolen refresh token can be detected.

Want to know if your app has this issue? Scan your live app or a public repo free, no account needed.

Scan my app →

Related: the decode-without-verify bug

What Is a JWT (JSON Web Token)? And the Common Mistake | Prbl