JWT decoder

Decode a compact JWS header and payload. The signature is never verified.

Docify's JWT decoder splits a compact JWS (RFC 7515 / RFC 7519) on ., base64url-decodes the header and payload (RFC 4648 §5), then JSON.parse / JSON.stringify(..., null, 2). An optional Bearer prefix is stripped. Decode is a button, not as-you-type. The signature segment is shown as base64url only — not HMAC, RSA, ECDSA, or JWKS verification. Not JWE. Nothing is uploaded.

Compact JWT
Header
Payload
Signature (base64url, not verified)

Signature segment will appear here...

How it works

  1. Decode is a button, not as-you-type. Load sample fills the input only. Copy writes the pretty-printed header and payload. Nothing is uploaded.
  2. A leading Bearer token (case-insensitive) is stripped, then whitespace is removed. The string is split on .. Exactly three segments are required. Five segments is JWE and is rejected.
  3. Header and payload are RFC 4648 §5 base64url (optional = padding is accepted), then UTF-8 via TextDecoder (fatal: true), then JSON.parse. Pretty-print is JSON.stringify(..., null, 2). Both must be JSON objects.
  4. The third segment is shown as the original base64url text. It is never verified. iat / exp / nbf numbers are displayed with new Date(n * 1000).toISOString() only. This is not a validator, not JWKS, and not a JWE decryptor.

FAQ

Does this decoder upload my token?
No. Decode and copy run in your browser. The page does not send the token to a server.
Does decoding verify the signature?
No. The page never checks HMAC, RSA, ECDSA, or alg none. It does not load a JWKS, accept a secret, or claim the token is valid, expired, or authentic. Header and payload are base64url-encoded JSON (RFC 4648 §5), not ciphertext. Anyone who has the compact string can read those objects.
What token shape is supported?
Compact JWS (RFC 7515 / RFC 7519): three base64url segments joined by dots (header.payload.signature). An optional leading Bearer prefix (Authorization header) is stripped, then remaining whitespace is removed. An unsecured JWT still has a trailing dot and an empty signature segment. Five segments is compact JWE (RFC 7516); this page does not decrypt. Two segments is rejected.
How are iat, exp, and nbf shown?
Those registered claims are NumericDate values: JSON numbers that mean POSIX seconds since 1970-01-01T00:00:00Z, leap seconds ignored (RFC 7519). When the claim is a finite number, the page shows new Date(n * 1000).toISOString() as a UTC display only. It does not compare them to the clock and does not treat a past exp as an invalid token.

Related