JWT decoder & local verifier

Local token inspection
JWT · HS256

Token verdict

Structure readable

signature unverified

Decoding reveals claims; it does not authenticate them. Verify issuer, audience, expiry, and signature in your application.

Issuertinapps-dev
Subjectada
Audienceexample-app
IssuedDec 31, 2025, 11:00:00 PM
ExpiresJun 12, 2034, 11:33:20 PM
Decoded token

Header

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

{
  "sub": "ada",
  "iss": "tinapps-dev",
  "aud": "example-app",
  "iat": 1767222000,
  "exp": 2033768000
}

Claim policy scan

  • Token lifetime exceeds 24 hours
StructureReadable
Expiryin 23,539 days
SignatureNot checked
Policy flags1

JWT Decoder

Decode a JSON Web Token's header and payload, read its claims as dates rather than epoch seconds, and verify an HMAC signature locally with a shared secret. Policy problems — no issuer, no audience, an expiry before the issue time, a lifetime measured in days — are flagged rather than left for you to spot.

Segments in every token
3
Verifiable here
HS256/384/512
Encoding, unpadded
base64url
Tokens uploaded
0

Step by step

How to use it

  1. 01Paste the token

    All three segments decode immediately — header, payload, and the signature left as-is. Nothing is transmitted, which is the only acceptable arrangement for a credential.

  2. 02Read the claims as dates

    iat, nbf, and exp are epoch seconds and unreadable at a glance. They are rendered as real timestamps, so an expiry that has already passed is obvious rather than arithmetic.

  3. 03Check the policy flags

    A missing issuer or audience, no expiry at all, an expiry before the issue time, or a lifetime over 24 hours are each called out. These are the findings that turn up in security reviews.

  4. 04Verify the signature, if it is HMAC

    Paste the shared secret and the HS256, HS384, or HS512 signature is checked in your browser. RS and ES tokens are signed with a private key and cannot be verified from a secret at all.

Worked example

What is actually in a token

Three base64url segments joined by dots. Two of them are readable by anyone who has the token, which is the fact that most misuse of JWTs comes down to.

Given

Format
header.payload.signature
Encoding
base64url, unpadded
Encryption
none

The three segments and who can read them

header     {"alg":"HS256","typ":"JWT"}
           anyone with the token

payload    {"sub":"1234","exp":1735689600,
            "role":"admin"}
           anyone with the token

signature  HMAC-SHA256(header.payload, secret)
           proves nobody altered the first two
           it does NOT hide them
Readable by anyone
header + payload
Signature proves
integrity
Signature hides
nothing

A signed JWT is tamper-evident, not confidential: base64url is an encoding and the payload is plain text to anyone holding the token — including the browser it was issued to. Putting an email, an internal user id, or a role hierarchy in there discloses all of it. If the contents must stay secret you need an encrypted token or an opaque one, not a signed one.

Before you trust a token

What to know about JWTs

Decoding is not verifying

Anyone can read a token's payload and anyone can craft one with whatever claims they like. Only checking the signature against a key you trust makes the contents meaningful. A backend that decodes without verifying is a backend that accepts any role its attacker types.

Never trust the alg header

The token tells you which algorithm it claims to use, and taking that at face value is the source of two classic vulnerabilities: alg: none, and an RS256 verifier tricked into treating a public key as an HMAC secret. Pin the expected algorithm server-side and reject anything else.

You cannot revoke a stateless token

Once issued, a JWT is valid until it expires — logging out, deleting the session, or banning the user changes nothing the verifier can see. That is why access tokens should have short lifetimes and why a denylist or a refresh-token exchange is needed for real revocation.

Expiry claims are seconds, and clocks drift

exp, iat, and nbf are epoch seconds, not milliseconds — a token with an exp in milliseconds is valid for about fifty thousand years. Verifiers also allow a small clock skew, so a token can be accepted a few seconds past its stated expiry.

Size travels with every request

A JWT rides in a header on every call, so a payload stuffed with permissions and profile data adds a kilobyte to every request and can hit proxy header limits. Keep claims to identifiers and look the rest up.

This decoder never sees your token

Decoding and HMAC verification both run in your browser using the Web Crypto API. That matters more here than anywhere: pasting a live token into a server-side decoder hands someone a working credential.

The judgement call

Should this be a JWT at all?

JWTs solve one problem well and are routinely used for several they solve badly.

  • Stateless auth between your own services

    Good fit

    The verifier needs only a key, not a database lookup. This is the case the format was designed for.

  • A short-lived access token

    Good fit

    Minutes, not days. Short lifetimes are what make the absence of revocation tolerable.

  • A long-lived session in a browser

    Use a session cookie

    Server-side sessions revoke instantly, stay small, and avoid storing a bearer token in JavaScript-reachable storage.

  • Carrying anything confidential

    Not signed JWT

    The payload is plain text to anyone with the token. Encrypt it, or use an opaque token and look the data up.

  • Permissions that change during a session

    Look them up

    Claims are frozen at issue time. A revoked admin keeps their admin claim until the token expires.

  • A token you need to invalidate on logout

    Needs state

    Statelessness is the trade. Real revocation means a denylist or short access tokens plus refresh exchange.

Reference

How a token is put together

Structure
header.payload.signatureThree base64url segments joined by dots. The first two are data; the third authenticates them.
Encoding
base64url, no paddingUses - and _ instead of + and / and drops the = padding, so standard Base64 decoding fails on it.
HMAC algorithms
HS256 · HS384 · HS512Shared-secret signatures, the only family verifiable from a secret — and the only ones this tool can check.
Asymmetric algorithms
RS · PS · ES familiesSigned with a private key and verified with a public one. A secret cannot verify them.
Time claims
exp · iat · nbfEpoch seconds. Milliseconds are a common bug and produce absurdly long-lived tokens.
Identity claims
iss · aud · subIssuer, audience, and subject. Verifying iss and aud is what stops a token issued for another service being replayed at yours.

FAQ

Questions, answered plainly

How do I decode a JWT?

Paste it in — the header and payload are base64url and decode immediately, with the time claims rendered as real dates. It happens entirely in your browser, which is the only safe way to inspect a live token.

Is a JWT encrypted?

No. A signed JWT is encoded, not encrypted: anyone holding the token can read the header and payload in full. The signature proves the contents have not been altered — it does not conceal them. Anything confidential belongs outside the token.

Can I verify a token here?

If it uses HMAC — HS256, HS384, or HS512 — paste the shared secret and the signature is checked locally with the Web Crypto API. RS, PS, and ES tokens are signed with a private key and cannot be verified from a secret, so those are decoded but not verified.

What is the alg: none attack?

A forged token that sets its algorithm header to none and omits the signature. A verifier that trusts the header and skips verification accepts it, along with whatever claims the attacker wrote. The defence is to pin the expected algorithm on the server and reject anything else — never read it from the token.

How do I revoke a JWT?

You cannot, without adding state. A signed token stays valid until it expires, which is the trade you accept for stateless verification. In practice: keep access tokens short-lived, use refresh tokens for renewal, and maintain a denylist if you need immediate revocation.

Is my token sent anywhere?

No. Decoding and HMAC verification both run in your browser. This matters more than for any other tool here — pasting a live token into a server-side decoder hands whoever runs it a working credential.

Decoding and HMAC verification both run in your browser via the Web Crypto API. No token or secret is ever transmitted.