What is a JWT token?

Last updated April 28, 2026
Short answer
A JSON Web Token is a string that an authentication server hands to a client after a successful login. It contains a small JSON blob describing who the user is, plus a signature that proves the server issued it. The client sends it back on every request so the server can trust who is calling without keeping a session record.

The anatomy of a JWT

A JWT is three Base64-URL-encoded chunks separated by dots:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiQWxpY2UifQ.K-EzFhRtkPm...

From left to right:

  1. Header: a JSON object that says which algorithm signs this token, e.g. {"alg":"HS256","typ":"JWT"}.
  2. Payload: the actual claims. The "who" and "what" of the token: user ID, name, expiry timestamp, scopes.
  3. Signature: a cryptographic signature over the first two chunks, using a key only the server knows (HMAC) or a private key (RSA / ECDSA).

Each chunk is Base64-URL-encoded, so you can copy a JWT into a chat or URL without worrying about special characters.

Decoding (not verifying) a JWT

Anyone with the token can read the payload. Try it: paste a JWT into any JWT decoder and you will see the JSON. This is by design - the payload is not secret, it is just signed.

The header and payload are not encrypted. Never put a password, an API key, or anything sensitive in a JWT payload. Put a user ID and a session reference if you need to.

The signature is what makes the token trustworthy. Without the server's key, an attacker cannot generate a token with a different payload that still passes verification.

Common claims

ClaimMeaning
subSubject - usually the user ID.
issIssuer - which server issued the token.
audAudience - which service the token is intended for.
expExpiry - Unix timestamp after which the token is invalid.
iatIssued-at timestamp.
nbfNot-before - earliest time the token is valid.
jtiA unique ID for this token, useful for revocation.

Beyond these standard claims, applications add their own (roles, scopes, tenant ID, etc.).

JWT vs sessions

The argument:

  • Sessions: server keeps a record of every active login. Client only carries an opaque session ID. Easy to invalidate (just delete the session row). Requires shared storage if you have multiple servers.
  • JWTs: server keeps no record. The token itself is the proof. Easy to scale horizontally (any server can verify with the same key). Harder to invalidate before expiry, because you would need a separate "revoked tokens" list anyway.

In practice most production systems use a mix: short-lived JWTs (15-60 min) for fast API auth, plus a longer-lived refresh token stored as a session-like record server-side so you can revoke it.

A pitfall to know about

Old JWT libraries had a famous bug: if you set alg: "none" in the header, some implementations would accept the token without verifying the signature. This let attackers forge any token they wanted.

Modern libraries refuse alg: none by default, and you should reject it explicitly when you accept JWTs. Always verify with the exact algorithm you expect.

TextLab: Format, Edit & Convert app icon

TextLab: Format, Edit & Convert

Decode JWTs, Base64, URLs, and more on iPhone, iPad, and Mac. Plus JSON pretty-printing and regex testing. · iPhone, iPad & Mac

Related entries