Allin1Tool
Developer ToolsRuns in your browser

JWT Decoder

Decode a JWT header and payload from base64url, with alg plus epoch, UTC and relative times for iat, nbf and exp claims.

Share:

JWT Decoder workspace

Source Editor

Input

Press Ctrl/Cmd + Enter to run.

Your draft is kept in this tab only (sessionStorage) and disappears when the tab closes. .

Result Console

Using JWT Decoder

  1. Paste the token into the editor, or press Load example to see the layout on a sample token.

  2. Press Decode Token to split it on the dots and decode the first two segments.

  3. Read the header for alg and kid, and the payload for the claims your application relies on.

  4. Check the iat, nbf and exp rows, shown as raw epoch seconds, UTC and relative local time.

The three dot-separated segments are decoded from base64url, so the hyphens and underscores that appear in most real tokens are handled correctly and multibyte claim values come back intact. Signatures are never checked, and the interface and the copied output both say so, because reading a payload proves only what a token asserts about itself.

A JSON Web Token is three base64url segments joined by dots: header, payload, signature. This page splits them, decodes the first two, and shows you the JSON inside. Everything a JWT claims about itself is readable by anyone holding it — that is by design, and it is the first thing to understand about the format.

Decoding is not verification

The payload rendered on this page is what the token asserts. It is not what an issuer has vouched for.

Anyone can build a token that says "role": "admin", base64url the pieces, staple any three characters on the end as a signature, and paste it here. It will decode perfectly, because decoding only reverses an encoding. What separates a real token from a forged one is the signature, and checking it requires the issuer's secret or public key — which this page does not have, does not ask for, and would not accept.

The interface says so next to the result, and the phrase travels with the copied output so it cannot be pasted into a ticket and mistaken for a validation. Verification belongs on your server, against the key from your identity provider's JWKS endpoint, using a library that also enforces the algorithm you expect. That last part is not optional: accepting whatever alg the token names is how the alg: none and RS256-downgraded-to-HS256 attacks work, and both were real breaks in real libraries.

The base64url difference, which used to break this page

JWT segments use the URL-safe alphabet from RFC 4648: - instead of +, _ instead of /, and the trailing = padding dropped, because tokens ride in URLs and Authorization headers.

The browser's atob does not accept that alphabet. Calling it on a raw JWT segment throws InvalidCharacterError the moment a - or a _ appears — and since those two characters stand in for two of sixty-four values, they show up in a large majority of real tokens. That was the previous behaviour here: paste a token from your own logs, get an error, conclude the token was malformed.

The decoder now translates the alphabet, restores the padding, and reads the bytes as UTF-8, so a name claim containing an accented character or a non-Latin script comes back intact rather than as mojibake.

Reading the time claims

Three registered claims from RFC 7519 carry timestamps, and all three count seconds since the Unix epoch rather than milliseconds — a factor of a thousand that has confused a great many people at three in the morning. Each is shown three ways: the raw number, the UTC ISO form, and a relative phrase in your local timezone.

  • iat — issued at, which tells you how old the token is and how long your lifetimes really are in practice.
  • nbf — not before, the moment until which the token is invalid.
  • exp — expires at, past which a correct verifier rejects it.

An expired or not-yet-valid token is flagged explicitly, which answers the question most people bring to a decoder.

What the header is telling you

The header names the algorithm in alg and often a key id in kid. HS256 is symmetric — the same secret signs and verifies, so both parties hold it. RS256 and ES256 are asymmetric: the issuer signs with a private key and anyone can verify with the public one. kid tells the verifier which key from the JWKS to fetch, which is what makes rotation possible. And alg: none means an unsigned token, which some libraries once accepted.

A word about what you are pasting

A JWT is a bearer credential: whoever holds it can act as the subject named in it until it expires. Nothing you paste here is transmitted, and there is no network call in this code path at all — which is precisely why a local decoder beats the first search result for this particular job. The token sits in sessionStorage for this tab only, and "Clear it now" removes it immediately.

To pull a base64url segment apart on its own, Base64 Encoder / Decoder handles the same alphabet. To reproduce an HMAC-SHA-256 signature when you do hold the secret, Hash Generator has an HMAC mode.

Frequently asked

Does a successful decode mean the token is genuine?

No, and this is the point worth internalising. Anyone can assemble a token claiming any role, staple arbitrary characters on as a signature, and it will decode here perfectly. Only signature verification against the issuer's key distinguishes a real token from a forged one, and that belongs on your server.

Why did other decoders reject my token as invalid?

JWT segments use the URL-safe alphabet, with hyphen and underscore standing in for plus and slash. The browser's atob throws on both characters, so a decoder calling it directly fails on the majority of real tokens. This one translates the alphabet and restores the padding first.

My token shows as not yet valid. What does that mean?

Its nbf claim sits in the future, so a correct verifier will reject it until that moment passes. In practice this almost always indicates clock skew between the issuing machine and yours rather than a problem with the token itself.

What should I look at in the header?

The alg value and the kid. HS256 is symmetric, so both parties hold the same secret; RS256 and ES256 are asymmetric, signed privately and verified with a public key. The kid tells a verifier which key to fetch, which is what makes rotation possible.