Local browser utility · Examples and limits included

JWT Decoder

Decode a JSON Web Token to read its header, payload, and expiry claims in your browser. This tool decodes tokens; it does not verify signatures.

This tool decodes. It does not verify.Anyone can read a JWT's header and payload — they are only Base64, not encryption. Proving a token is genuine means checking its signature against the issuer's secret or public key, which cannot happen in a page like this one. Treat everything below as claims the token makes about itself, not facts you have confirmed.

Need an example?

The token is decoded in this page. Avoid pasting a live production token you cannot rotate.

Decoded locally in your browser No data is sent to any server

What the result contains

What This Tool Provides

Read what a JSON Web Token actually contains: the algorithm named in its header, every claim in its payload, and what its expiry and issued-at times mean in ordinary dates. Decoding happens in this page — the token is never sent anywhere. This tool decodes; it does not verify signatures, and the difference matters more than anything else on this page.

  • Header JSON with the algorithm the token names
  • Payload JSON exactly as the issuer wrote it
  • Registered claims explained, with exp, iat, and nbf as readable dates
  • Warnings for an expired token, a future nbf, or alg: none

How to Use This Tool

  1. Paste the tokenDrop in the three dot-separated segments. A leading "Bearer " from a copied Authorization header is stripped for you.
  2. Read the header and payloadBoth cards show the decoded JSON with line numbers, and each has its own copy button.
  3. Check the claimsThe claims card leads with "Signature not verified", then reads exp, iat, and nbf as UTC dates with the distance from now, so an expired token is obvious.

How It Works

A JWS compact token is three base64url segments joined by dots: header.payload.signature. Base64url is an encoding, not encryption — it exists so arbitrary bytes survive a URL or an HTTP header, and it reverses without any key at all. This tool splits on the dots, converts the base64url alphabet back to standard Base64, decodes the bytes, and parses each of the first two segments as JSON. The third segment is measured and described but never checked, because checking it requires the issuer’s HMAC secret or public key. Registered numeric claims are read as epoch seconds and rendered as ISO instants alongside how far away they are.

Worked Examples

A standard HS256 token

Input
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkYSBMb3ZlbGFjZSJ9.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U
Output
{"alg":"HS256","typ":"JWT"} · {"sub":"1234567890","name":"Ada Lovelace"}

Both segments decode with no key. That is the point being made: the payload of a signed token is readable by anyone who holds it.

An expiry claim in context

Input
{"exp":1767225600}
Output
exp 1767225600 → 2026-01-01T00:00:00Z

Epoch seconds become an instant you can compare against now, and the tool says outright when that moment has already passed.

A token claiming no signature

Input
eyJhbGciOiJub25lIn0.eyJzdWIiOiJhZG1pbiJ9.
Output
Warning: the header states alg: none

The classic forgery: strip the signature and set alg to none. It decodes perfectly, which is exactly why decoding proves nothing.

Decoding Is Not Verification

A JWT carries two separate things: data anyone can read, and a signature only the issuer could have produced. This page reads the first and reports the existence of the second. It cannot tell you whether a token is genuine, because that answer requires the shared HMAC secret or the issuer’s public key — and a secret pasted into a public web page would stop being a secret.

The practical consequence: never make an authorization decision from a decoded payload. A token whose payload reads <code>{"role":"admin"}</code> looks identical here whether it was issued by your identity provider or typed by hand thirty seconds ago. Verification belongs on your server, in a library that checks the signature, the algorithm, the issuer, the audience, and the expiry together.

What Each Segment Holds

The three segments of a JWS compact token
SegmentContainsReadable without a key?
Headeralg and typ, sometimes a kid naming which key signed itYes
PayloadClaims: sub, iss, aud, exp, iat, plus anything the issuer addedYes
SignatureHMAC or asymmetric signature over the first two segmentsPresent, but only checkable with the key

Registered Claims Worth Knowing

RFC 7519 registered claims and what they assert
ClaimMeaningCommon mistake
expExpiry, in epoch secondsReading it as milliseconds, which puts 1767225600 in 1970
iatIssued atAssuming it proves freshness without also checking exp
nbfNot valid beforeIgnoring it, so a token is accepted early
iss / audIssuer and intended audienceVerifying the signature but never checking who the token was for
subSubject the token describesTreating it as a display name rather than an opaque identifier

Where the Token Came From, and Where It Goes Next

Tokens rarely arrive alone. If yours came out of a config file or an Authorization header stored as a blob, the surrounding value is often Base64 too, and decoding that outer layer first leaves you with the three dot-separated segments this tool expects. If it arrived inside a redirect URL, every dot may be intact but the padding characters percent-escaped, so decoding the percent-encoding comes first.

Once the payload is open, the work usually continues elsewhere. Large payloads read far better formatted as JSON, especially when a claim holds a nested object of permissions. Timestamps beyond the three this page explains — a custom <code>renewed_at</code>, say — can be converted from epoch seconds to a date one at a time. When you are comparing a token that works against one that does not, a line-by-line diff of the two payloads finds the differing claim faster than reading both. And if you are generating the identifiers that end up in <code>sub</code> or <code>jti</code>, a version 4 or version 7 UUID is the usual choice, while a SHA-256 digest is what you want for fingerprinting a key rather than a claim.

Important Edge Cases

  • A five-segment token is a JWE, not a JWS: its payload is encrypted and cannot be read here at all.
  • Base64url uses - and _ where standard Base64 uses + and /, and drops the = padding, so a JWT segment pasted into a plain Base64 decoder often fails.
  • A token copied from a terminal can carry a line break in the middle; the segments then decode as invalid base64url.
  • Duplicate claim keys survive JSON.parse with the last value winning, exactly as they would in the issuing service.
  • Payloads are not required to contain exp at all, and a token without one does not expire on its own.

Limitations

  • Signatures are never verified. This tool cannot tell a genuine token from a forged one.
  • Encrypted JWE tokens are rejected rather than partially decoded.
  • Claims are reported as the issuer wrote them; the tool does not check iss, aud, or scope against anything.
  • Relative times are computed from your device clock, so a badly set clock will misreport how long is left.
  • No token is stored or remembered between visits, which also means there is no history to compare against.

Input handling

Private Browser Processing

The token is decoded inside the page with no network request. It is not sent to Tiny Tiny Tools and does not appear in the page URL or in an analytics event.

Google Analytics measures normal page visits, but these tool implementations do not send field values, generated passwords, QR payloads, uploaded QR images, or camera frames to analytics or a Tiny Tiny Tools processing endpoint.

Safety note: A JWT usually is a live credential. Decoding one locally is safe, but treat a token you paste anywhere as exposed, and rotate it if it belongs to production.

See the Privacy Policy for site-wide details.

Questions About This Tool

Can this tool tell me whether a token is valid?

No, and no browser tool can. Validity means the signature checks out against the issuer’s secret or public key, which is never available to a page like this. This tool decodes the readable parts and reports what the token claims about itself.

Is a JWT encrypted?

A standard signed JWT is not. Its header and payload are base64url, an encoding that reverses without a key, so anyone holding the token can read its claims. Only JWE tokens, which have five segments, are encrypted.

Why does my token say it expired when it works fine?

The exp claim is compared against your device clock. A clock that is wrong, or a token issued in a different timezone context but read as epoch milliseconds instead of seconds, produces exactly this confusion.

What does alg: none mean?

It means the token asserts that it carries no signature. Any library that honours that header will accept a payload anyone can write, which is why it is a well-known attack and why this tool warns about it.

Is it safe to paste a production token here?

The decoding happens on your device and nothing is uploaded, which you can confirm in the network counter above. Even so, a token is a credential: prefer a test token, and rotate anything production you paste into any tool.