How to decode a JWT without confusing decoding with verification
Inspect a JWT header and payload locally, read common claims, and separate token debugging from server-side signature, issuer, audience and time validation.
Decoding shows what the token claims. Signature verification checks that the
signed bytes match the selected key and were not changed after signing. Claim
validation then decides whether the issuer, audience, time and permissions are
acceptable. Reading the payload is useful while debugging a 401 or 403,
but it is not enough for an authorization decision.
| Operation | Key required | What it proves |
|---|---|---|
| Decode | No | The header and payload have a readable structure |
| Verify signature | HMAC secret or an asymmetric public key | The signed bytes were not changed and were produced by someone with the signing key |
| Validate claims | Service configuration | iss, aud, exp, nbf and other claims are acceptable for this API |
Open the JWT decoder, paste a test token and select Decode. devdeck expects three dot-separated segments, reads the header and payload as UTF-8 JSON objects, and prints them with indentation. It does not verify the signature.
What the three JWT parts contain
A typical signed JWT looks like this:
header.payload.signature
The header often contains alg, typ and kid. The payload contains
claims such as iss (issuer), sub (subject), aud (audience), exp
(expiration), nbf (not before) and application-specific values. The
signature binds the first two segments to a signing key.
Header and payload use Base64URL, not encryption. Anyone who receives the token can read them. A password, API key or other secret therefore does not belong in the payload. The guide to decoding Base64 locally explains the difference between ordinary Base64 and the URL-safe variant.
Do not trust alg, roles or sub just because they appear as clean JSON.
Before signature verification, an attacker can change those values and build a
new string. The verifier must restrict allowed algorithms itself and select a
key from trusted configuration.
Read the payload while debugging
For an authorization failure, inspect claims in this order:
iss: did the expected service issue the token?aud: is this token intended for your API?exp: has it expired? NumericDate is normally expressed as Unix-time seconds.nbf: is the token being used before its valid time?sub,scope,roles: do the user and permissions match the request?kidin the header: can the verifier find the intended key?
The JWT decoder shows raw values and does not calculate a final validity
status. Even a plausible exp can be changed along with the rest of the
payload. After visual inspection, reproduce the request through the real
verifier in your backend or identity provider.
If the payload is awkward to compare with the expected shape, copy the decoded object into JSON formatter. The formatter checks syntax and makes nesting readable. It still does not know the token contract or verify the signature.
Why a token does not decode
| Symptom | What to check |
|---|---|
| Not three dot-separated parts | A Bearer prefix, whitespace, truncation or a different format |
| Invalid Base64URL | An extra character entered the segment or part of the token is missing |
| Header or payload is not JSON | The value is not an ordinary JWT or the segment is damaged |
| Five parts instead of three | It may be compact JWE and needs a separate decryption flow |
It decodes but the API returns 401 | Signature, key, algorithm, issuer, audience and time |
The API returns 403 | The token may be valid but lack the required scope or role |
devdeck does not strip a Bearer prefix automatically, so paste the token
from the first header character through the signature. For alg: none, the
decoder accepts an empty third segment as the valid shape of an unsecured JWT.
That does not make the token trustworthy.
A safer debugging workflow
Local processing removes an upload request to devdeck, but a bearer token is still an access secret. Prefer a test or revoked token, do not share screenshots containing the full value, and clear the field after inspection. Browser extensions, clipboard history and screen recording do not become safe merely because there is no backend.
Before changing authentication code, record:
- the
issandaudexpected by the verifier; - the server time compared with
expandnbf; - the algorithms allowed by configuration;
- the
kidand key set used; - where the token was only decoded and where it was actually verified.
That record separates convenient JSON inspection from the trust decision and
usually narrows a 401 faster than repeatedly generating new tokens.
Questions
Can I decode a JWT without a secret or public key?
Yes. The header and payload of an ordinary three-part JWT use Base64URL and can be read without a key. A key is required for cryptographic signature verification, not for reading.
Does the devdeck JWT decoder verify the signature?
No. It displays the header and payload but does not prove that the token is authentic. Never make an access decision from decoded output alone.
Is Base64URL encryption?
No. It is a way to represent bytes with URL-safe characters. JWT claims are normally visible to anyone who has the token.
Is the JWT sent to the devdeck server?
No. Decoding runs in the browser, and the token or decoded header and payload are not included in analytics.