Reading a JWT: What Decoding Shows and What It Proves
Reading a JWT: What Decoding Shows and What It Proves
A JWT is three base64url segments, and decoding one tells you nothing about whether it is genuine. How to read the claims, and why tokens break in URLs.
Original workflow visual
Reading a JWT: What Decoding Shows and What It Proves
Understand
Review before moving forward
Check
Review before moving forward
Apply
Review before moving forward
The header and payload of a standard signed JWT are base64url text, not ciphertext. Anyone who obtains the token — from a URL, a log file, a browser devtools panel, a Referer header — can read every claim inside it without any key. The signature protects integrity, not confidentiality: it proves the token has not been altered, and proves nothing about who is allowed to see it. Never put anything in a payload that you would not put in a log line.
A decoder splits the token and base64-decodes two segments. That operation always succeeds on well-formed input, including on a token someone constructed by hand. Verification is a separate step that recomputes the signature using the secret or public key and compares it. A debugging tool showing you a neat, plausible payload is not evidence that the token is genuine. Trusting a claim because it decoded cleanly is the root of a whole family of authentication bugs.
JWTs use the URL-safe alphabet: minus and underscore replace plus and slash, and the trailing equals padding is stripped. Pasting a JWT into a standard base64 decoder often fails on the padding or mangles bytes on the substituted characters. This is also why a token can survive one system and break in the next — something helpfully "fixed" the encoding along the way, or a URL decoder turned a legitimate character into something else.
exp is the expiry, iat the issue time, and nbf the earliest time the token is valid. All three are numeric Unix timestamps in seconds, not milliseconds, which is a frequent source of tokens that appear to expire in 1970 or in the far future. Because clocks between issuer and verifier drift, implementations usually allow a small leeway of a few seconds. If tokens fail intermittently right at issue time, an nbf claim combined with a fast clock on the issuing server is a good first suspect.
A JWT in a query string is exposed in browser history, server access logs, and the Referer header sent to third parties. It is also fragile: tokens are long, some proxies and older clients truncate URLs beyond a few thousand characters, and a token that is percent-encoded once by one layer and again by another arrives corrupted. If a token works in a header and fails in a link, compare the two strings character by character before suspecting anything else — double encoding is the usual answer.
The header names the signing algorithm, and a naive verifier reads it and does what it says. Two classic attacks follow. The first sets alg to none and drops the signature entirely. The second switches an RS256 token to HS256 so that the server verifies using the public key as if it were an HMAC secret — and the public key is public. The fix in both cases is the same: the verifier decides which algorithm is acceptable in advance and rejects anything else, rather than taking direction from the token it is checking.
When a token misbehaves, decode the header and payload first and write down alg, exp, iat, nbf and any audience or issuer claims. Confirm the clock units are seconds. Compare the raw token string from the working path and the failing path character by character. Only after the payload is understood should you move to signature verification with the expected algorithm and key. If the algorithm in the header is not on your allowlist, reject the token without attempting verification.
Common Questions
A standard signed JWT is not. The payload is base64url text that anyone with the token can read. Encryption requires the separate JWE format.
No. Decoding always succeeds, including on a forged token. Only signature verification against the correct key establishes trust.
Usually encoding. JWTs use base64url, and a URL decoder or a double-encoding layer can alter the minus, underscore or padding characters.
Whether exp is in seconds. A millisecond timestamp is a thousand times too large, and a seconds value fed to a millisecond parser lands in 1970.
Related Tools
JWT Encoder
Generate HS256, HS384 or HS512 JSON Web Tokens directly in the browser for testing and local workflows.
JWT Decoder
Decode JWT header and payload locally, inspect claims, expiry times and raw Base64URL segments.
URL Parser
Break a URL into protocol, host, path, query and hash fields, then inspect every parameter clearly.
Query String Builder
Build clean query strings from key-value pairs and preview the final URL segment instantly.
JSON Minify
Minify JSON instantly in the browser and remove unnecessary whitespace before shipping data elsewhere.
URL Encoder / Decoder
Encode/decode URL components or full URLs and inspect query parameters.
Slug Generator
Turn titles or phrases into clean URL-friendly slugs with case, separator and trim options.