JWT Decoder

Paste a JSON Web Token to see its header and payload as formatted JSON, every claim explained in plain language, and timestamps such as exp and iat converted to dates with "expires in" times. Safety checks flag unsigned tokens, expired or not-yet-valid tokens, very long lifetimes and claims that look sensitive. For HS256, HS384 and HS512 tokens you can verify the signature with the shared secret. Decoding runs entirely in your browser, but you should still never paste production tokens.

Don't paste production tokens or secrets. This decoder runs only in your browser and sends nothing anywhere, but a live token is a password: anyone who sees it (screen sharing, browser extensions, screenshots) can use it until it expires. Use test tokens, or revoke a token after inspecting it.

Input

340 characters

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzhmMmE5MSIsIm5hbWUiOiJBbmEgRXhhbXBsZSIsImVtYWlsIjoiYW5hQGV4YW1wbGUuY29tIiwic2NvcGUiOiJyZWFkOnByb2plY3RzIHdyaXRlOnByb2plY3RzIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLmV4YW1wbGUuY29tIiwiYXVkIjoiZXhhbXBsZS1hcGkiLCJpYXQiOjE3OTAwMDAwMDAsImV4cCI6MTg5MzQ1NjAwMH0.ASLZOBC2nvepZXIcSf6v-O7BF95FclQzlIQhRnK1Nrg

Decoded

Header
{
  "alg": "HS256",
  "typ": "JWT"
}
Payload
{
  "sub": "user_8f2a91",
  "name": "Ana Example",
  "email": "ana@example.com",
  "scope": "read:projects write:projects",
  "iss": "https://auth.example.com",
  "aud": "example-api",
  "iat": 1790000000,
  "exp": 1893456000
}

Claims

ClaimMeaningValue
subSubject: the user or entity the token is aboutuser_8f2a91
nameFull nameAna Example
emailEmail addressana@example.com
scopeGranted permissionsread:projects write:projects
issIssuer: who created and signed the tokenhttps://auth.example.com
audAudience: who the token is intended forexample-api
iatIssued at1790000000
expExpiration time1893456000

Verify an HMAC signature (optional)

For HS256, HS384 and HS512 tokens you can check the signature with the shared secret. Verification uses your browser's Web Crypto; the secret never leaves this page. The sample token's secret is demo-secret-change-me.

Runs entirely in your browser. Nothing you paste or open here is uploaded or stored.

How to use the JWT decoder

  1. Paste the token. A Bearer prefix copied from a header is removed automatically.
  2. Read the coloured token: header, payload and signature are shown in different colours.
  3. Check the decoded header and payload, then the claims table with dates in UTC and relative times.
  4. Review the checks for expiry, algorithm and risky claims.
  5. Optionally verify an HMAC signature by entering the shared secret. The sample token’s secret is demo-secret-change-me.

How a JWT is built

A JWT is three Base64URL-encoded parts joined by dots: header.payload.signature.

  • The header names the algorithm (alg, for example HS256 or RS256) and usually the type (typ: JWT) and key ID (kid).
  • The payload holds claims. Registered claims include iss (issuer), sub (subject), aud (audience), exp (expiry), nbf (not before), iat (issued at) and jti (token ID). Times are seconds since 1 January 1970 UTC.
  • The signature is computed over the first two parts. With HS256 it’s an HMAC-SHA256 using a shared secret; with RS256 it’s an RSA signature that anyone can check with the public key.

Decoding needs no key. Verifying does.

Worked examples

Example 1: the sample token

The sample decodes to a user with read and write scopes, issued by auth.example.com for example-api. The checks show it’s signed with HS256 and not expired, but valid for over three years, which is far too long for an access token. Enter the secret and verification succeeds; change one character of the secret and it fails.

Example 2: debugging a 401 error

Paste the token your app is sending. If the check says Expired 2 h ago, the client isn’t refreshing tokens. If aud doesn’t match your API’s identifier, the server rejects it even though the signature is valid.

Example 3: an unsigned token

A token with "alg": "none" and an empty signature is flagged in red. Servers must never accept these, because anyone can create them. Allow-list the algorithms your server accepts.

Good practice for JWTs

  • Keep access tokens short-lived (minutes to an hour) and use refresh tokens.
  • Always validate exp, nbf, iss and aud on the server, with a few seconds of clock skew.
  • Don’t store sensitive data in the payload; it’s readable.
  • Store browser tokens in HttpOnly cookies where possible, to limit theft by scripts.

Common mistakes

  • Trusting a decoded token without verifying it. Anyone can edit the payload and re-encode it.
  • Using a weak HMAC secret. Short secrets can be brute-forced offline; use at least 32 random bytes.
  • Confusing JWS with JWE. A five-part token is encrypted and can’t be decoded without its key.
  • Millisecond timestamps. JWT times are in seconds; a 13-digit exp is a bug.

Frequently asked questions

Is it safe to paste a JWT here?

The decoder runs only in your browser and sends nothing anywhere. Even so, a valid token works like a password until it expires, and it can leak through screen sharing, screenshots or browser extensions. Use test tokens, or revoke a real one after inspecting it.

Can anyone read the contents of a JWT?

Yes. A standard signed JWT (JWS) is only Base64URL-encoded, not encrypted. The signature proves who issued it and that it wasn't changed, but anyone holding the token can read the payload. Never put passwords or personal secrets in claims.

Why can't I verify an RS256 token here?

RS256, ES256 and similar algorithms use a key pair: the issuer signs with a private key, and you verify with its public key, usually published at a JWKS URL. Verify those on your server with a maintained library; this tool verifies shared-secret (HMAC) tokens only.

What does “expired” mean if my app still accepts the token?

The exp claim is a promise, not an enforcement mechanism. If an expired token is still accepted, the server isn't checking exp, which is a security bug worth fixing.

What are the three parts of a JWT?

A header (algorithm and token type), a payload (the claims, such as user id and expiry) and a signature. Each is Base64URL-encoded and separated by dots.

Sources