How to use JWT Debugger
- 1. Paste a JWT. Drop a compact token (three base64url segments) into the editor. A leading Bearer prefix is stripped automatically.
- 2. Read header and payload. Header typically contains alg and typ. Payload contains claims such as sub, iss, aud, iat, nbf, and exp.
- 3. Check expiry. If exp is present, PureDevKit shows a live countdown. Expired tokens are flagged without contacting an issuer.
- 4. Optional HS256 check. If you already have the HMAC secret, you can verify HS256 locally. Never paste production secrets into a shared machine.
About this tool
JSON Web Tokens are defined in RFC 7519. A compact JWT is three base64url-encoded segments separated by dots: header, payload, and signature. They are commonly used as bearer credentials for APIs and as session tokens in SPAs. Decoding a JWT is not the same as validating it. Anyone can decode the payload; only a holder of the correct key can verify the signature. PureDevKit decodes in-browser so you can inspect claims without leaking a credential to a third-party debugger.
Header, payload, and signature
The header is a JSON object, usually `{ "alg": "HS256", "typ": "JWT" }`. `alg` names the algorithm that produced the signature. The payload is a JSON object of claims. Registered claim names include `iss` (issuer), `sub` (subject), `aud` (audience), `exp` (expiration, seconds since epoch), `nbf` (not before), `iat` (issued at), and `jti` (token id). The third segment is the signature over `base64url(header) + '.' + base64url(payload)`. For HMAC algorithms the same secret is used to sign and verify. For RSA or ECDSA, a private key signs and a public key verifies.
Expiry and clock skew
`exp` is a Unix timestamp in seconds, not milliseconds. A token with `exp: 1893456000` expires at that instant in UTC. Verifiers should reject tokens after `exp` and before `nbf`. In distributed systems, a few seconds of clock skew is normal; libraries often allow a leeway of 30–60 seconds. If your token looks expired here but works against an API, compare browser time, server time, and whether the claim was issued in milliseconds by mistake (a very common bug).
What this debugger will not claim
Decoding does not prove the token is authentic. Without the key, a signature is just bytes. PureDevKit can optionally recompute HS256 in Web Crypto if you supply the secret, which is useful for local tests. It does not implement full JWS/JWE, key rotation, `kid` lookup, or audience enforcement. Treat this as an inspector, not an authorization server. Never paste a production private key. If a token has already been exposed in a screenshot or a ticket, rotate it.
Security properties of JWTs
JWTs are bearer tokens: possession is proof as far as the API is concerned. Send them only over TLS, store them carefully (httpOnly cookies are usually safer than `localStorage` for session JWTs), and keep lifetimes short. Do not put sensitive PII in the payload; it is only encoded, not encrypted. If you need confidentiality, use JWE or keep the data on the server. Prefer `alg` allow-lists on the verifier so a token cannot switch to `none`.
Code examples
Node decode
const [h, p] = token.split(".");
const payload = JSON.parse(Buffer.from(p, "base64url").toString());Python
import base64, json
p = token.split(".")[1] + "=="
print(json.loads(base64.urlsafe_b64decode(p)))Claims check
if (payload.exp * 1000 < Date.now()) throw new Error("expired");
if (payload.aud !== "api.example.com") throw new Error("aud");