A decoded header
Input
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Result
{ "alg": "HS256", "typ": "JWT" }HS256 is symmetric: the same secret signs and verifies. RS256 is asymmetric, so verifiers only need the public key.
Decode JSON Web Tokens and inspect header, payload, and expiry timestamps.
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "1234567890",
"name": "DevToolBox",
"iat": 1750000000,
"exp": 1750003600
}Issued at: 2025-06-15T15:06:40.000Z
Expires at: 2025-06-15T16:06:40.000Z
Understand the format
A JWT carries its claims in plain sight: the header and payload are only Base64URL-encoded, and the signature is the sole part that proves anything.
A signed JSON Web Token is three Base64URL segments joined by dots: header.payload.signature. The header declares the signing algorithm and token type. The payload holds the claims. The signature is computed over the first two segments with a secret or private key, and it is the only part that ties the claims to an issuer you trust.
Because the first two segments are merely encoded, anyone holding the token can read every claim inside it. Never place data in a JWT payload that the bearer should not see. Encoding is not encryption; the separate JWE standard exists for tokens whose contents must stay confidential.
This page decodes. It does not check the signature, and by design it cannot: verification requires the issuer key, which should never be pasted into a web page. A token can decode perfectly, show exactly the claims you expect, and still be forged, expired, or issued by the wrong environment.
Proper verification happens on the server and checks several things together: the signature against the expected key, that the algorithm matches what you expect rather than what the token requests, the issuer and audience, and the time claims. The historical "alg: none" vulnerability came from libraries trusting the header instead of enforcing a configured algorithm.
Step by step
The token is split and decoded in the page using the browser Base64 and JSON APIs. It is never uploaded, logged, or stored, and no signature key is required or accepted.
Worked examples
Input
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Result
{ "alg": "HS256", "typ": "JWT" }HS256 is symmetric: the same secret signs and verifies. RS256 is asymmetric, so verifiers only need the public key.
Input
"iat": 1750000000, "exp": 1750003600
Result
Issued at 2025-06-15T15:06:40Z, expires 2025-06-15T16:06:40Z
Both claims are Unix seconds, not milliseconds. The difference here is a one-hour lifetime.
Reference
| Claim | Name | What it means |
|---|---|---|
| iss | Issuer | Who created the token. Must match the issuer your service trusts. |
| sub | Subject | Who or what the token is about, usually a user identifier. |
| aud | Audience | Who the token is for. A service must reject tokens addressed elsewhere. |
| exp | Expiration time | Unix seconds after which the token must be rejected. |
| nbf | Not before | Unix seconds before which the token is not yet valid. |
| iat | Issued at | Unix seconds when the token was created. |
| jti | JWT ID | Unique identifier, used to detect replay or to revoke a single token. |
Practical Guide
Troubleshooting
FAQ
A signed JWT is not. The header and payload are Base64URL-encoded and readable by anyone holding the token. Encrypted tokens use the separate JWE format.
No, deliberately. Verification needs the issuer secret or key, and pasting that into any web page would be a serious mistake. Verify in your backend or with your identity provider library.
HS256 uses one shared secret for signing and verification, so every verifier can also mint tokens. RS256 signs with a private key and verifies with a public one, which is what you want when many services validate tokens.
It is unsigned, with an empty signature segment. Unsigned tokens must never be accepted by a service that relies on the claims.
Decoding happens entirely in your browser and nothing is transmitted. Even so, treat the token as a live credential: clear it when you are finished and prefer a token that has already expired.
Go deeper