Paste a JSON Web Token to instantly decode its header and payload, check expiry status, and verify HS256/384/512 signatures — entirely in your browser.
A JSON Web Token (JWT, standardized in RFC 7519) is a compact, URL-safe way to represent a set of claims — statements about a user or entity — that can be verified and trusted because it's digitally signed. A JWT consists of three Base64URL-encoded segments separated by dots: a header describing the token's type and signing algorithm, a payload containing the actual claims, and a signature that lets a receiving system verify the header and payload haven't been altered since signing.
JWTs are the backbone of modern stateless authentication: instead of a server keeping a session record for every logged-in user, it issues a signed token containing the user's identity and permissions, and any service that trusts the signing key can verify the token independently without querying a shared session store. This makes JWTs especially popular in distributed systems and microservice architectures, where checking a token's signature locally is far cheaper than making a network call to a central session service on every single request.
The header is a small JSON object, almost always containing just two fields: alg (the signing algorithm, like HS256 or RS256) and typ (always 'JWT'). It's Base64URL-encoded to form the first segment of the token. The payload is where the actual claims live — it can contain any of the seven standard registered claims (iss, sub, aud, exp, nbf, iat, jti) alongside any number of custom, application-defined claims, and forms the second segment once encoded.
The signature is computed by taking the encoded header and payload, joining them with a dot, and running that string through the algorithm specified in the header — either an HMAC (for HS256/384/512, using a shared secret) or a digital signature (for RS256/ES256/PS256, using a private key). The resulting signature becomes the third segment. Critically, changing even a single character of the header or payload after signing produces a completely different signature, which is exactly the property that lets a verifier detect tampering.
HMAC-based algorithms (HS256, HS384, HS512) use a single shared secret for both signing and verifying — simple to set up, but every party that needs to verify tokens must also hold the same secret that can sign new ones, which means any service capable of verification is also capable of forging valid tokens. This makes HMAC signing best suited for systems where the same trusted party both issues and verifies tokens, like a single backend service.
Asymmetric algorithms (RS256, ES256, PS256, and others) use a private/public key pair: the issuer signs with a private key it keeps secret, and distributes the corresponding public key freely to any service that needs to verify tokens. A service holding only the public key can confirm a token is authentic but cannot forge new valid tokens itself, which is exactly the separation of powers needed in larger systems with many independent services — an auth provider issues tokens, and dozens of downstream microservices can each verify them locally using a publicly published key, without any of them being able to mint fraudulent tokens.
The most well-known JWT vulnerability is the 'alg: none' attack, where an attacker sets the header's algorithm to 'none' and strips the signature entirely — a poorly implemented verifier that trusts whatever algorithm the token claims to use, rather than enforcing an expected algorithm server-side, can be tricked into accepting a completely unsigned, freely editable token as valid. A related attack targets systems that support both symmetric and asymmetric algorithms: if a verifier is misconfigured to accept HS256 while its actual key is an RSA public key (which is often a publicly known, non-secret value), an attacker can sign a forged token using that public key as an HMAC secret, since the verifier can't tell an HMAC signature from an RSA one just by looking at the bytes.
Other frequent mistakes include never checking exp at all (accepting tokens forever), storing sensitive data in the payload under the mistaken assumption that signing implies encryption, and using an overly simple, guessable HMAC secret that's vulnerable to brute-force. The defensive pattern that avoids all of these: always explicitly specify and enforce the expected algorithm when verifying (never trust the token's own alg claim to decide how to verify it), always check exp and nbf server-side even though this tool shows them for convenience, and never put anything in a JWT payload you wouldn't be comfortable displaying in plain text.
JWT Decoder inspects one specific kind of signed token. These related developer tools cover the encodings and identifiers you'll often encounter working with JWTs and authentication.