JWTs Explained: Decoding Claims Without Confusing Them With Validation
JWTs Explained: Decoding Claims Without Confusing Them With Validation
A practical explanation of JWT structure, claims, Base64URL encoding, signatures, and why decoding a token is not the same as trusting it.
Original workflow visual
JWTs Explained: Decoding Claims Without Confusing Them With Validation
Decode parts
Review before moving forward
Read claims
Review before moving forward
Validate trust
Review before moving forward
Most JWTs are written as three dot-separated segments: header, payload, and signature. The header usually states the token type and signing algorithm. The payload contains claims such as subject, issuer, audience, expiration, and application-specific fields. The signature protects the header and payload from modification when verified with the correct key. The first two parts are encoded, not encrypted. Anyone with the token can usually read them.
A claim is a statement inside the payload. The subject might identify a user, the audience might identify an API, and the expiration might define when the token should stop working. Those statements are useful only if the token is valid for the current application. An attacker can write a payload that says anything. Trust comes from signature verification, issuer checks, audience checks, time checks, and application authorization rules.
The exp, iat, and nbf claims are usually NumericDate values measured in seconds. Developers often compare them with millisecond timestamps from JavaScript, which creates dates far in the future or past. Clock skew also matters when servers disagree by a small amount. When debugging an expired or not-yet-valid token, convert the claim to UTC first, then compare it with server time and the policy your application actually enforces.
The issuer tells you who created the token, and the audience tells you who the token is meant for. These checks stop a token from one environment or service being accepted by another. A token issued for staging should not work in production. A token issued for a profile API should not automatically work against a billing API. Many real JWT bugs are not cryptographic failures; they are missing issuer or audience checks.
The verifier should not blindly trust whatever algorithm appears in the header. Application configuration should define allowed algorithms and keys. Public key rotation, key identifiers, and JSON Web Key Sets can make verification flexible, but they also add failure modes when caches are stale or keys are misconfigured. Decoding the header can help explain a failure, but the verifier must still enforce its own rules.
Many JWTs are bearer tokens: whoever has the token can use it until it expires or is revoked by the surrounding system. That means raw tokens should not be pasted into tickets, analytics, screenshots, chat logs, or unnecessary online tools. For debugging, use a synthetic token or redact the signature and sensitive claims when possible. If a real token was exposed, treat it like any other leaked credential.
Start by decoding the header and payload locally. Read iss, aud, sub, exp, iat, nbf, roles, scopes, and environment markers. Convert times to UTC. Then check whether the rejecting service expects the same issuer, audience, algorithm, key, and clock tolerance. If those are correct, move to authorization logic: the token may be valid but still lack permission. This order keeps token debugging from becoming a random search through backend code.
Common Questions
No. Decoding only reveals the header and payload. Validation requires signature, issuer, audience, time, and policy checks.
Usually no. Standard JWT payloads are encoded, not encrypted, so sensitive data should not be placed there casually.
Common causes are audience mismatch, issuer mismatch, key rotation, clock skew, missing scopes, or environment confusion.
Avoid sharing the raw token. If a teammate only needs claim structure, provide a decoded payload with subject, email, token ID, signature, and environment-specific identifiers replaced by placeholders. Keep claim names, time values, issuer, audience, and scope shape if those details are relevant to the failure.
Validation answers whether the token should be trusted. Authorization answers whether the trusted subject can perform a specific action. A token can have a correct signature and still lack the required role, scope, tenant membership, account state, or resource-level permission.
Raw bearer tokens should not be logged because possession can be enough to use them. Log a token ID, request ID, or redacted claim summary instead.