What is a JSON Web Token (JWT)?

A JSON Web Token — JWT, often pronounced "jot" — is a compact, URL-safe way to represent claims between two parties. It's defined by RFC 7519 and is one of the most widely used token formats in modern web authentication and API authorization.

The short answer

A JWT is a string with three Base64URL-encoded parts separated by dots: header.payload.signature. The header says how the token is signed, the payload carries the claims (who the user is, when the token expires, etc.), and the signature lets the server verify the token hasn't been tampered with.

Anatomy of a JWT

A real JWT looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0IiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzE4MDAwMDAwfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1. Header

A small JSON object describing the token type and the signing algorithm:

{
  "alg": "HS256",
  "typ": "JWT"
}

2. Payload

A JSON object containing claims — statements about the user and metadata about the token. Standard registered claims include sub (subject), iss (issuer), aud (audience), exp (expiration), iat (issued-at), and nbf (not-before). You can also add your own custom claims.

{
  "sub": "1234",
  "name": "Jane Doe",
  "role": "admin",
  "iat": 1718000000,
  "exp": 1718003600
}

Important: the payload is only encoded, not encrypted. Anyone with the token can read it. Never put passwords, API keys, or other secrets inside the payload.

3. Signature

The signature is what makes a JWT trustworthy. The server computes:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

On every request, the server recomputes the signature using its secret and compares. If anyone modified a single character of the header or payload, the signatures won't match and the token is rejected.

Signing algorithms

  • HS256 / HS384 / HS512 — HMAC with SHA-2. Symmetric: the same secret signs and verifies. Simplest and fastest. Use when one system both issues and verifies tokens.
  • RS256 / RS384 / RS512 — RSA signatures. Asymmetric: a private key signs, a public key verifies. Use when many services need to verify without holding the signing key.
  • ES256 / ES384 / ES512 — ECDSA. Same public/private split as RSA, but with shorter keys and signatures.
  • EdDSA — Modern signing with Ed25519. Recommended for new systems that support it.
  • none — No signature. Never accept this in production; algorithm-confusion attacks use it to forge tokens.

Need a secret for HS256? Generate one with the JWT Secret Generator and check it with the strength validator.

How JWT authentication works

  1. The user signs in with a username and password.
  2. The server verifies the credentials and issues a JWT containing the user's identity and an expiration time.
  3. The client stores the token (ideally in an httpOnly cookie) and sends it on every request, typically in the Authorization: Bearer <token> header.
  4. The server verifies the signature with its secret or public key, checks the expiration, and trusts the claims inside.

Because the server can verify the token without a database lookup, JWTs scale well across distributed systems and microservices.

When to use JWTs (and when not to)

Good fit

  • Stateless APIs and microservices
  • Mobile and SPA authentication
  • Federated identity (OIDC, SSO)
  • Short-lived access tokens

Not a good fit

  • Storing sensitive data (payload is readable)
  • Long-lived sessions you may need to revoke instantly
  • Simple server-rendered apps with a single backend

Security checklist

  • Use a strong secret (≥ 256 bits for HS256) — generate one with the generator.
  • Pin the expected algorithm; never trust the header's alg.
  • Reject alg: none at the library level.
  • Always set a short exp (5–15 minutes for access tokens).
  • Validate iss and aud.
  • Use refresh tokens stored server-side for longer sessions.
  • Rotate signing keys regularly and use a kid header for rollovers.

Frequently asked questions

What does JWT stand for?

JWT stands for JSON Web Token. It's an open standard (RFC 7519) for representing claims securely between two parties as a compact, URL-safe string.

Is a JWT encrypted?

No. A standard JWT is signed, not encrypted — anyone with the token can decode the header and payload. Never put passwords or secrets inside a JWT payload. If you need confidentiality, use JWE (JSON Web Encryption).

How long should a JWT secret be?

At minimum 256 bits (32 bytes) for HS256, 384 bits for HS384, and 512 bits for HS512. Always generate the secret from a cryptographically secure random source — never use a passphrase.

What's the difference between a JWT and a session token?

A session token is just an opaque ID; the server looks it up in a session store. A JWT is self-contained — the claims travel inside the token, so the server can verify it without a database lookup.

Where should I store a JWT in the browser?

Prefer an httpOnly, Secure, SameSite=Strict cookie. Storing JWTs in localStorage exposes them to XSS attacks.

Try it now

Ready to use JWTs in your project? Start with a strong secret.