JWT Decoder
Paste a JSON Web Token to read its header, its payload and the exp, nbf and iat times in UTC. The signature is shown but not checked: nothing is verified. How it works
Use the JWT Decoder
Up to 100,000 characters. Decoded in this browser only; nothing is verified.
- Nothing is verified. The signature is not checked, so this shows what the token says, not that it is genuine or unaltered.
Summary
- Algorithm (alg)
- HS256
- Type (typ)
- JWT
- Subject (sub)
- 1234567890
- Expiry (exp)
- none in the payload
32 bytes when decoded. Algorithm named in the header: HS256.
Time claims
| Claim | Value | UTC | Your time zone | Against this device's clock |
|---|---|---|---|---|
| Issued at (iat) | 1516239022 | 2018-01-18T01:30:22Z | … | … |
These are the times the token states. Whether it is expired is judged by this device's clock, which may be wrong, and the signature is not checked.
About the JWT Decoder
A JWT is three Base64URL parts joined by dots, header.payload.signature, and the first two decode to JSON that anyone can read. The jwt.io sample token decodes to the header {"alg":"HS256","typ":"JWT"} and a payload whose iat of 1516239022 is 2018-01-18T01:30:22Z. This JWT decoder shows the signature but never checks it, so a decoded token tells you what it claims, not that it is genuine. A Summary box lists alg, typ, iss, sub, aud and jti when present, and whether exp has passed.
Registered JWT claims (RFC 7519, section 4.1)
| Claim | Name | What it identifies | How the decoder shows it |
|---|---|---|---|
| iss | Issuer | The principal that issued the token | In the payload, as written, and in the Summary |
| sub | Subject | The principal the token is about | In the payload, as written, and in the Summary |
| aud | Audience | The recipients the token is intended for | In the payload, as written, and in the Summary |
| exp | Expiration time | The time on or after which the token must not be accepted | Row Expires (exp) under Time claims: UTC, your time zone and a status against this device’s clock |
| nbf | Not before | The time before which the token must not be accepted | Row Not before (nbf) under Time claims: UTC, your time zone and a status against this device’s clock |
| iat | Issued at | The time the token was issued | Row Issued at (iat) under Time claims: UTC, your time zone and a status against this device’s clock |
| jti | JWT ID | A unique identifier for the token | In the payload, as written, and in the Summary |
All seven are optional. The Summary also shows alg and typ from the header, and an Expiry (exp) row that says none in the payload when the token has no exp. exp, nbf and iat are NumericDate values: seconds since 1970-01-01T00:00:00Z UTC, ignoring leap seconds.
The jwt.io sample token, decoded
| Part | Base64URL text | Decoded |
|---|---|---|
| Header | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 | {"alg":"HS256","typ":"JWT"} |
| Payload | eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ | {"sub":"1234567890","name":"John Doe","iat":1516239022} |
| Signature | SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c | 32 bytes, not checked |
| iat claim | 1516239022 | 2018-01-18T01:30:22Z |
The decoder lays the JSON out one member per line and keeps every value as the token wrote it.
What the decoder says about unusual tokens
| Token | Result |
|---|---|
| Bearer eyJhbGciOi… (pasted with the prefix) | The Bearer prefix is removed and the token decodes as usual. |
| header.payload. (empty third part) | There is no signature (an unsecured token). |
| A header with "alg": "none" | The header says alg "none": the token claims to be unsigned, and a server must never accept it as proof of anything. |
| Five parts | This has 5 parts, which is an encrypted token (JWE). Its payload is encrypted and cannot be read without the key. |
| A part with + or / in it | The header is not valid Base64URL text (letters, digits, - and _ only). |
| "exp": 1700000000000 (milliseconds) | Looks like milliseconds: the value is above 100,000,000,000 seconds (the year 5138). RFC 7519 uses seconds. Read as milliseconds it would be 2023-11-14T22:13:20Z. |
| More than 100,000 characters | Token is too long (maximum 100,000 characters). |
Frequently asked questions
- Does decoding a JWT verify it?
- No. Decoding only reverses the Base64URL encoding. The signature is computed over the header and payload (RFC 7515), and checking it needs the secret or public key of whoever issued the token. This decoder shows the signature text and its size but never calls a token valid; verify it on your server with a JWT library before trusting any claim.
- How do I check when a JWT expires?
- Read its exp claim, a count of seconds since 1970-01-01T00:00:00Z. The decoder converts it: an exp of 1516242622 is 2018-01-18T02:30:22Z, one hour after the sample token’s iat. It also shows the time in your zone and whether it has passed by this device’s clock, which can be wrong. A value in milliseconds, such as 1700000000000, is flagged, with the date it would be as milliseconds: 2023-11-14T22:13:20Z.
- Is it safe to paste a JWT into this decoder?
- The token is decoded by JavaScript in this page. The decoder does not put it in the address bar, save it or send a request with it. A live token is still a credential that works until it expires, so paste a test or expired token when you can, and press Clear token when you are done.
- What does alg none mean in a JWT?
- RFC 7519 section 6 calls a token whose header says "alg": "none" an Unsecured JWT: it has no signature, so anyone can write one with any claims. The decoder flags it, and a token with an empty third part is flagged as having no signature.
- Why does my token have five parts instead of three?
- It is an encrypted token (JWE). Its compact form has five Base64URL parts, the protected header, encrypted key, initialization vector, ciphertext and authentication tag (RFC 7516 section 7.1), and its claims cannot be read without the key. The decoder says so instead of decoding it.
Related Tools
View all toolsSubnet Mask Calculator
Subnet calculator for IPv4: enter an address and a mask or prefix such as /24 to get the network, broadcast address, host range, usable hosts and wildcard mask.
CIDR Calculator
Enter an IPv4 CIDR block such as 192.168.1.0/24 for its IP range, netmask, broadcast address and usable hosts, split it into subnets or turn a range into CIDR.
URL Parser
Split a URL into protocol, user name, password, host, port, path, query and hash, see each query parameter decoded, and whether the port was written.
Query String to JSON
Paste a query string or a full URL to get JSON: repeated keys and key[] become arrays, + and %20 decode to spaces, with optional nesting and number types.
JSON to Query String
Turn a JSON object into a URL query string: arrays as repeated keys, [], [0], a comma list or JSON, nested objects as user[name], user.name or JSON.
JWT Expiration Checker
Decode a JWT and compare its exp, nbf and iat claims with your clock to see Expired or Not expired and the time left. The signature is not verified.