What is a JWT? JSON Web Tokens Explained

A JSON Web Token (JWT, pronounced "jot") is a compact string that carries a set of claims — statements such as "this is user 42, with the admin role, valid until 15:00" — together with a cryptographic signature that lets the receiver check the claims were issued by someone it trusts and have not been altered. JWTs are the standard token format for API authentication, OAuth 2.0 access tokens and OpenID Connect ID tokens.

This guide explains what is inside a token, what the standard claims mean, how to decode and verify one, and the security rules that separate a safe implementation from a breach.

The three parts of a JWT

A JWT is three Base64URL-encoded segments separated by dots: header.payload.signature. Base64URL is Base64 with URL-safe characters and no padding, so the token can travel in headers, query strings and cookies.

  • Header — JSON describing the token type and the signing algorithm, e.g. {"alg": "HS256", "typ": "JWT"}. It may also carry a kid (key id) that tells the verifier which key to use.
  • Payload — the claims, as a JSON object. Anything can go here, but it is only encoded, not encrypted: anyone who has the token can read it.
  • Signature — computed over the encoded header and payload with the algorithm named in the header. HS256 uses a shared secret (HMAC); RS256 and ES256 use a private key to sign and a public key to verify.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiI0MiIsIm5hbWUiOiJMYXlsYSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTc1NjcwMDAwMCwiZXhwIjoxNzU2NzAzNjAwfQ
.4l3Y2cYpXqZ0cVZ5m4Q8n1fGx0y8s3oT0kq4rV7cWvA

header  → {"alg":"HS256","typ":"JWT"}
payload → {"sub":"42","name":"Layla","role":"admin","iat":1756700000,"exp":1756703600}

Try it: JWT Decoder

Standard claims and what they mean

  • iss (issuer) — who created the token, usually the auth server URL.
  • sub (subject) — who the token is about, typically the user id.
  • aud (audience) — which service the token is intended for. A verifier must reject tokens meant for another audience.
  • exp (expiration) — a Unix timestamp after which the token is invalid. Short lifetimes (minutes for access tokens) limit the damage of a leak.
  • nbf (not before) and iat (issued at) — timestamps that bound when the token became valid and when it was minted.
  • jti (JWT id) — a unique id, used to detect replay or to revoke a specific token.
  • Custom claims — roles, permissions, tenant id, email. Keep them small: the token is sent with every request.

Try it: JWT Claims Analyzer Try it: JWT Expiration Checker

Decoding is not verifying

Decoding a JWT means Base64URL-decoding the header and payload to read them. Anyone can do that with no key at all — which is exactly why you must never trust a decoded payload on its own. Verifying means recomputing the signature with the right key and algorithm and confirming it matches, then checking exp, nbf, iss and aud.

An online decoder is the right tool for reading a token while debugging: seeing which user it names, which roles it carries and when it expires. It is not a security check, and a decoder that runs in your browser is the only kind you should paste a real token into.

Try it: JWT Decoder Try it: JWT Header Analyzer

HS256 vs RS256 vs ES256

  • HS256 (HMAC with SHA-256) — one shared secret both signs and verifies. Simple, fast, fine when a single service issues and consumes the tokens. Every party that can verify can also forge.
  • RS256 (RSA signature) — a private key signs, a public key verifies. Any service can verify with the published public key (often via a JWKS endpoint) without being able to mint tokens. The default for OAuth providers.
  • ES256 (ECDSA with P-256) — same asymmetric model as RS256 with much smaller keys and signatures.
  • none — an algorithm that means "no signature". Verifiers must reject it; accepting alg=none is one of the classic JWT vulnerabilities.

Try it: JWT Generator Try it: HMAC Generator

JWT security rules

  • Verify the signature and pin the algorithm on the server. Never let the token's own header decide which algorithm to use.
  • Always check exp, and check aud and iss against your own values.
  • Never put secrets, passwords or sensitive personal data in the payload — it is readable by anyone holding the token. Use JWE if you need encryption.
  • Keep access tokens short-lived and use a refresh token to obtain new ones.
  • Store tokens carefully in browsers: an HttpOnly, Secure, SameSite cookie is safer than localStorage, which any injected script can read.
  • Use a strong secret for HS256 — at least 256 bits of randomness, never a password.
  • Plan for revocation: a JWT is valid until it expires, so a logout or a compromised account needs a denylist (jti) or short lifetimes.

Try it: Random Secret Generator Try it: OAuth Token Decoder

JWTs in OAuth 2.0 and OpenID Connect

OAuth 2.0 access tokens are often JWTs, though the spec does not require it; OpenID Connect ID tokens always are. An ID token describes the authenticated user (sub, email, name) for the client application; an access token grants the client permission to call an API (scope, aud). They are verified the same way, but an ID token must never be sent to an API as if it were an access token.

Try it: OAuth Token Decoder

Frequently asked questions

Is a JWT encrypted?

No — a standard signed JWT (JWS) is only Base64URL-encoded. Its payload is readable by anyone who has the token. Encrypted tokens exist (JWE) but are much less common.

Can a JWT be decoded without the secret?

Yes. The header and payload are plain Base64URL, so any decoder can read them. The secret or key is only needed to verify the signature, which is what proves the token is authentic.

How do I check if a JWT has expired?

Decode it and compare the exp claim (a Unix timestamp in seconds) with the current time. A verifier library does this automatically; an online decoder shows the expiry as a readable date.

What is the difference between a JWT and a session cookie?

A session cookie is an opaque id that the server looks up in its own store; a JWT carries the session data itself, signed, so the server needs no lookup. JWTs scale across services more easily; sessions are simpler to revoke.

Where should I store a JWT in a web app?

Prefer an HttpOnly, Secure cookie with SameSite set, so JavaScript on the page cannot read it. localStorage is convenient but exposes the token to any cross-site scripting bug.

Is it safe to paste a JWT into an online decoder?

Only if the decoder runs entirely in your browser and never sends the token anywhere. The Mutqan JWT decoder works locally; even so, treat production tokens as secrets and prefer test tokens when you can.

Tools mentioned in this guide

Decode JWT header and payload, inspect claims and check expiration — entirely in your browser.

Security Open tool

Decode OAuth 2.0 / OpenID Connect access and ID tokens and understand scopes, audiences and lifetimes.

Security Open tool

Generate HMAC signatures (SHA-256/384/512/SHA-1) for webhook and API request signing.

Security Open tool

More guides

More guides →