Back to blog
Security9 min read

How to Decode a JWT: Header, Payload, Signature & Security

Learn how to decode a JSON Web Token (JWT) by hand and with tools, understand its header, payload, and signature, read standard claims, and avoid the security mistakes that break authentication.

By Saifur Rahman Shochib

A JSON Web Token (JWT) is the compact, URL-safe token that powers most modern authentication: API logins, single sign-on, and session-free auth all ride on it. When something breaks — a 401 that should be a 200, a user who can read another tenant's data — the first debugging step is almost always to decode the token and read what is actually inside. This guide explains exactly what a JWT contains, how to decode each part, and the security rules that separate a safe implementation from a vulnerable one.

What is a JWT?

A JWT, defined by RFC 7519, is a compact way to represent claims — statements about a user or a request — as a JSON object that is digitally signed. Because it is self-contained, a server can verify a JWT without a database lookup: the token itself carries the user ID, roles, and expiry, and the signature proves it has not been tampered with.

That self-contained design is why JWTs dominate stateless authentication. The token is issued once at login, sent on every subsequent request (usually in the Authorization header as a Bearer token), and validated cryptographically on arrival.

The three parts of a JWT

A JWT is three Base64URL-encoded segments joined by dots: header.payload.signature. Each dot separates a distinct piece. Base64URL is a URL-safe variant of Base64 that replaces plus and slash with dash and underscore and drops padding, so the token can travel in URLs and headers without further escaping.

The header describes how the token is signed (for example the algorithm HS256 or RS256 and the token type JWT). The payload holds the claims. The signature is computed over the header and payload using the signing key, and it is what makes the token trustworthy.

Three Base64URL segments joined by dotstext
eyJhbGciOiJIUzI1NiJ9 . eyJzdWIiOiIxMiIsImV4cCI6MTcwMH0 . SflKxwRJSMeKF2QT4fwpM
└─── header ───┘       └────── payload ──────┘          └──── signature ────┘

How to decode a JWT

Decoding a JWT means Base64URL-decoding the header and payload back into readable JSON. Split the token on the dots, decode the first segment to see the algorithm, and decode the second to see the claims. The third segment, the signature, is raw bytes and is not meant to be read as text.

A JWT decoder tool does this instantly and formats the JSON for you, which is far safer and faster than pasting tokens into a generic Base64 decoder. Crucially, decoding is not the same as verifying: anyone can read a JWT's contents because the payload is only encoded, not encrypted.

Header (first segment, decoded)json
{ "alg": "HS256", "typ": "JWT" }
Payload (second segment, decoded)json
{ "sub": "12", "name": "Ada", "exp": 1700000000 }

Standard JWT claims

RFC 7519 defines a set of registered claims with reserved meanings. You will see these short three-letter keys in almost every token:

  • iss (issuer) — who created and signed the token
  • sub (subject) — the principal the token is about, usually a user ID
  • aud (audience) — the intended recipient; verify this matches your service
  • exp (expiration) — a Unix timestamp after which the token is invalid
  • nbf (not before) — a timestamp before which the token must be rejected
  • iat (issued at) — when the token was created
  • jti (JWT ID) — a unique identifier used to prevent replay

Decoding versus verifying — the critical distinction

The single most common JWT mistake is treating decode as if it were verify. Decoding reveals the claims; verifying checks the signature against a trusted key and confirms the token has not been altered or forged. A token whose claims you can read is not a token you can trust until the signature checks out.

Many libraries expose two functions — one that only decodes and one that verifies — and developers occasionally call the decode-only path on incoming tokens. The result is an application that accepts any token a user invents. Always verify the signature, the expiry, and the audience on every request before trusting a single claim.

JWT security pitfalls to avoid

  • The alg:none attack — RFC 7518 defines a none algorithm meaning unsigned. If your verifier accepts it, attackers can forge tokens. Always pin an explicit allowlist of algorithms and reject none.
  • Algorithm confusion — accepting both HS256 and RS256 can let an attacker sign a token with the public key. Fix the expected algorithm server-side.
  • Sensitive data in the payload — because the payload is readable by anyone, never put passwords, secrets, or PII in a JWT.
  • No expiry — always set exp, and keep access tokens short-lived; use refresh tokens for longevity.
  • Skipping audience checks — validate aud so a token issued for one service cannot be replayed against another.

Decode a JWT safely

To inspect a token, split it on the dots and decode the header and payload, or paste it into a client-side JWT decoder that runs entirely in your browser so the token never leaves your machine. This matters: a JWT is a live credential, and pasting a production token into a server-side online tool effectively hands over a valid session.

Once decoded, you can copy the payload into a JSON validator or formatter to inspect nested claims, confirm the exp timestamp, and check that the issuer and audience are what you expect. For local debugging, that read-only inspection is exactly what you need — just remember to verify the signature in code before trusting anything.

Frequently asked questions

Is a JWT encrypted?

No. A standard signed JWT (a JWS) is only Base64URL-encoded, not encrypted, so anyone who has the token can read the header and payload. Signing proves integrity, not confidentiality. If you need the contents hidden, use an encrypted JWT (JWE) and never put secrets in a signed token's payload.

Can I decode a JWT without the secret key?

Yes. Decoding only requires Base64URL-decoding the segments, which needs no key. The secret or public key is only required to verify the signature, not to read the claims.

Is it safe to decode a JWT in an online tool?

Only if the tool runs entirely in your browser and never transmits the token. Because a JWT is a working credential, prefer a client-side decoder for any real token, and never paste production tokens into a service that processes them on a server.

How do I check if a JWT is expired?

Decode the payload and read the exp claim, which is a Unix timestamp (seconds since 1970). If the current time is past exp, the token is expired. In code, your JWT library checks this automatically during verification.

Why does a JWT use Base64URL instead of Base64?

Base64URL is URL- and header-safe: it replaces the plus and slash characters with dash and underscore and omits padding, so the token can be placed in URLs, cookies, and HTTP headers without additional escaping.

Related tools

Try these tools

Keep reading

Related guides