beginner·8 min read·Updated Oct 19, 2026

What Is a JWT? JSON Web Token Structure & Claims

A JWT packs identity claims into a signed string. Here's what's inside the header, payload and signature, and how a server decides to trust it.

This lesson is part of API 101, our free beginner course, and follows API keys. It explains the concept. If you're here to test JWT-protected APIs, jump to our JWT authentication testing guide.

What a JWT is

A JWT (JSON Web Token, pronounced "jot") is a compact, signed string that carries claims — statements about a user or client — so an API can authenticate a request without looking up a session.

It is defined in RFC 7519. "Self-contained" means the token itself holds the user info plus a signature proving nobody changed it. The server verifies the signature and then trusts the claims.

The three parts

A JWT is three Base64URL-encoded segments separated by dots:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiQWxpY2UifQ.sig_bytes_here
↑ header              ↑ payload                              ↑ signature

Decode the first two and you get JSON.

Header — which algorithm signed the token, and the token type:

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

Payload — the claims:

{
  "sub": "user-123",
  "email": "alice@example.com",
  "role": "admin",
  "iat": 1712345678,
  "exp": 1712349278
}

Signature — HMAC-SHA256(base64url(header) + "." + base64url(payload), secret) for HS256, or an RSA/ECDSA signature for asymmetric algorithms such as RS256 and ES256.

Anyone can decode a JWT — the payload is not encrypted, only signed. Never put secrets (passwords, card numbers) in it.

Registered claims

RFC 7519 registers seven standard claim names. All are optional; your API decides which it requires.

ClaimMeaning
issIssuer — who created the token
subSubject — who the token is about (usually a user ID)
audAudience — which API the token is meant for
expExpiration — Unix timestamp after which the token is invalid
nbfNot Before — Unix timestamp before which it's invalid
iatIssued At — when it was created
jtiJWT ID — a unique identifier, useful for revocation

On top of these, apps add their own claims (role, tenant_id, scope, permissions). Times are in seconds since the Unix epoch, not milliseconds — a common source of "token already expired" confusion.

JWS, JWE and "JWT"

People say "JWT" for what is almost always a JWS — a signed token (RFC 7515). A JWE (RFC 7516) is an encrypted token whose payload you can't read without the key; it has five segments instead of three. If you can paste a token into a decoder and read the payload, it's a JWS.

Symmetric vs asymmetric signing

HS256 (HMAC)RS256 / ES256 (RSA / ECDSA)
KeysOne shared secret signs and verifiesPrivate key signs, public key verifies
Who can verifyOnly services that hold the secretAnyone with the public key (often published as a JWKS URL)
Typical useA single service issuing and checking its own tokensAn identity provider issuing tokens that many APIs verify

See it in the sandbox

Log in to receive a token:

POST/auth/login
Log in and receive a JWT.
curl -X POST 'https://demo.totalshiftleft.ai/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"demo@totalshiftleft.ai","password":"demo123"}'

Response:

{
  "access_token": "eyJhbGciOi...",
  "refresh_token": "eyJhbGciOi...",
  "expires_in": 900
}

Send the access_token as a bearer token to call a protected endpoint:

GET/api/v1/me
Call a protected endpoint with Authorization: Bearer <token>.
curl -X GET 'https://demo.totalshiftleft.ai/api/v1/me'

Add the header Authorization: Bearer eyJhbGciOi.... Without it, you get 401.

How a server verifies a JWT

On every request, the server:

  1. Reads the Authorization: Bearer <token> header.
  2. Splits the token into header, payload and signature.
  3. Checks that alg is the algorithm it expects (and never none).
  4. Recomputes or verifies the signature with the secret or public key.
  5. Compares signatures in constant time.
  6. Checks exp is in the future and nbf is in the past, allowing a small clock skew.
  7. Checks iss and aud, and optionally jti against a revocation list.
  8. Only then treats the claims as trusted.

JWT vs session cookies

A session stores state on the server and gives the client an opaque ID; every request means a lookup, and logging out is just deleting the session. A JWT moves the state into the token, so any service can verify it without a shared store — but you can't easily "un-issue" it before exp. That trade-off is why access tokens are short-lived and paired with refresh tokens.

Common JWT pitfalls

These are the design mistakes the JSON Web Token Best Current Practices (RFC 8725) warns about:

  1. Accepting alg: none. An unsigned token must never be trusted.
  2. Algorithm confusion. If a server trusts the header's alg, an RS256 token can be re-signed as HS256 using the public key as the "secret". Pin the algorithm on the server.
  3. Weak HMAC secrets. Short secrets can be brute-forced offline from a single token. Use at least 256 bits of randomness.
  4. Long expirations. A token valid for 30 days is a stolen credential for 30 days. Keep access tokens short-lived.
  5. No revocation plan. Use short expiry plus refresh tokens, a jti deny-list, or a per-user "tokens issued before X are invalid" timestamp.
  6. Sensitive data in the payload. It's readable by anyone holding the token.
  7. Storing tokens where scripts can read them. In browsers, localStorage is exposed to XSS; HttpOnly, Secure, SameSite cookies are safer.

Testing JWT-protected APIs

This lesson stops at the concept. For the testing side — the positive, negative and security cases for expired, tampered, alg: none and wrong-audience tokens — use these guides:

Sources and further reading

What's next

JWTs answer "who is calling?". For delegated, machine-to-machine access, the standard is OAuth 2.0 client credentials.

Frequently asked questions

What is a JWT used for?+

Mostly for API authentication: after login, the client sends the JWT as a bearer token on each request, and the API verifies its signature and claims instead of looking up a session. It's also used to pass identity between services.

Is a JWT encrypted?+

Usually not. A standard JWT is signed (JWS), so its payload is only Base64URL-encoded and anyone can read it. Encrypted tokens (JWE) exist but are less common.

What are the three parts of a JWT?+

A header (algorithm and type), a payload (the claims) and a signature, each Base64URL-encoded and joined by dots.

What is the difference between a JWT and an API key?+

An API key is an opaque secret the server must look up; it identifies a client but carries no data. A JWT carries signed claims and an expiry, so the server can verify it on its own. See API keys.

What is the difference between a JWT and OAuth 2.0?+

OAuth 2.0 is a framework for getting tokens; a JWT is one format a token can take. Many OAuth servers issue access tokens as JWTs, but they don't have to.

How do you check a JWT expiration time?+

Read the exp claim in the payload, which is a Unix timestamp in seconds, not milliseconds. The token is valid only while exp is in the future, and servers usually allow a small clock skew. Mixing up seconds and milliseconds is a common cause of tokens that look already expired.

How does a server check a JWT token?+

It reads the bearer token, confirms the alg header is the expected algorithm and never none, verifies the signature with the secret or public key in constant time, checks exp and nbf, and checks iss and aud before trusting any claims.

What JWT security test cases matter most?+

Test that the API rejects expired tokens, tampered tokens, tokens with alg set to none, and tokens issued for a different audience. Also check for algorithm confusion, where an RS256 token is re-signed as HS256, and for weak HMAC secrets.

Related lessons

Read more on the blog