Skip to main content

← Back to blog

What Is a JWT? How JSON Web Tokens Work (and How to Read One)

If you’ve built or debugged a login system, you’ve met the JWT — a compact token that travels between client and server to prove who someone is. Here’s how it works and how to read one safely.

The three parts

A JWT is three Base64URL strings joined by dots: header.payload.signature.

  • Header — metadata, mainly the signing algorithm, e.g. {"alg":"HS256","typ":"JWT"}.
  • Payload — the claims, a JSON object of data about the user and token.
  • Signature — a cryptographic signature over the header and payload, created with a secret (or private key), used to detect tampering.

You can split and read the first two parts with a JWT decoder.

Common claims

The payload holds claims — some standardized:

  • sub — subject (usually the user ID).
  • iss — issuer (who created the token).
  • iat — issued-at time (a Unix timestamp).
  • exp — expiry time (a Unix timestamp). After this, the token should be rejected.
  • aud — intended audience.

Plus any custom claims your app adds (roles, email, etc.).

How JWTs are used for auth

In a typical stateless flow: you log in, the server returns a signed JWT, and your client sends it on every request (usually in an Authorization: Bearer … header). The server verifies the signature and checks exp — if valid, it trusts the claims without a database lookup. That statelessness is the main appeal.

Signed, not (usually) encrypted

Most JWTs are signed (JWS), not encrypted. Signing proves integrity and authenticity, but the payload is only Base64URL-encoded — anyone can read it. So:

  • Never put secrets in the payload (passwords, API keys, private data).
  • Encryption is a separate thing (JWE) and much less common.

Security rules that matter

  • Always verify the signature server-side with your secret/public key. Decoding (like our tool does) is not verification.
  • Check exp. An expired token must be rejected.
  • HS256 vs. RS256: HS256 uses one shared secret; RS256 uses a private key to sign and a public key to verify — better when multiple services need to verify but not issue.
  • Never paste a real secret key into an online tool. Decoding a token to inspect claims is fine; verifying requires the key and belongs in your own code.

Reading a token

To debug an auth issue — is the token expired? does it have the right role? — decode it and inspect the payload. The free JWT decoder shows the header and payload and converts exp to a readable time, all locally in your browser so the token is never uploaded.