JWT Encoder/Decoder
Free online JWT (JSON Web Token) encoder and decoder tool. Create JWT tokens or decode and analyze existing tokens instantly. View header, payload, signature, and claims information. Supports HMAC algorithms (HS256, HS384, HS512). Perfect for developers working with authentication, OAuth, and API security.
JWT Encoder/Decoder - Create and Decode JSON Web Tokens Online
A powerful online JWT (JSON Web Token) encoder and decoder tool that allows you to create new JWT tokens or decode, inspect, and understand existing tokens instantly. Encode header and payload with HMAC signing (HS256, HS384, HS512), or decode the header (JOSE header), payload (claims), and signature of any JWT token. View standard claims like issuer, subject, audience, expiration time, and more. Perfect for developers, security professionals, and anyone working with JWT-based authentication, OAuth 2.0, OpenID Connect, and API security.
What is a JWT and how is it structured?
A JSON Web Token (JWT, pronounced "jot") is an open standard (RFC 7519) for representing claims as a compact, URL-safe string. A JWT has three Base64URL-encoded parts joined by dots: header.payload.signature. The header declares the signing algorithm and token type ({"alg":"HS256","typ":"JWT"}). The payload contains claims like sub (subject), iss (issuer), exp (expiration), and any custom data. The signature is computed by hashing the encoded header+payload with a secret (HMAC) or signing with a private key (RSA/ECDSA). The token is base64url, not base64, so it's safe to put in URLs and HTTP headers. JWTs are stateless: the server validates the signature on each request without database lookups. RFC 7519 is the JWT spec; RFC 7515 covers JWS (signed) and RFC 7516 covers JWE (encrypted).
What is the alg=none vulnerability and how do I prevent it?
alg=none is the most famous JWT vulnerability, listed in the OWASP API Security Top 10. A token signed with alg=none has no signature at all — yet many older libraries would accept it as "valid" because the algorithm field in the header was honored without checking against an allowlist. An attacker could take a real token, change the header to {"alg":"none"}, strip the signature, modify the payload (e.g., role=admin), and the broken validator would let it through. The fix is to maintain a strict allowlist of acceptable algorithms server-side (e.g., only HS256 or RS256) and reject everything else — never trust the alg claim from the token itself. The companion bug is HS256/RS256 confusion: an attacker submits an HS256 token signed with the server's public RSA key as the HMAC secret. Always pin the expected algorithm per key.
What's the difference between HS256, RS256, and ES256?
HS256 (HMAC-SHA256) uses a single shared secret for both signing and verification — fast and simple but every party that can verify can also forge. Use it only when issuer and verifier are the same service. RS256 (RSA-SHA256) uses asymmetric crypto: a private key signs, a public key verifies. This is the standard for OAuth/OIDC because identity providers (Auth0, Okta, Google) publish a JWKS (JSON Web Key Set) endpoint with public keys clients fetch to verify tokens. ES256 (ECDSA P-256) is also asymmetric but uses elliptic curves, producing much shorter signatures (~64 bytes vs ~256 bytes for RS256) — better for bandwidth-constrained scenarios. EdDSA (RFC 8037) using Ed25519 is the modern recommendation: faster, smaller, and resistant to many timing attacks. Avoid RS256 with keys under 2048 bits.
What are the standard registered claims (iss, sub, aud, exp, nbf, iat, jti)?
RFC 7519 defines seven registered claims, all optional but recommended. iss (issuer) identifies who created the token. sub (subject) is the user ID. aud (audience) lists the intended recipients — your service must reject tokens where its identifier isn't in aud. exp (expiration time) is a Unix timestamp after which the token must be rejected — keep it short (15 min for access tokens). nbf (not before) is the earliest time the token is valid, useful for scheduled activation. iat (issued at) records when the token was created. jti (JWT ID) is a unique identifier per token, enabling revocation lists or replay detection. All time claims are NumericDate (Unix seconds since 1970 UTC). Always validate exp, nbf, iss, and aud — skipping any of these is a common bypass.

Where should I store JWTs in the browser — cookie or localStorage?
Neither is perfect. localStorage is vulnerable to XSS: any script on your origin can read it and exfiltrate the token. Cookies are vulnerable to CSRF if not properly configured, but mitigations are well understood. The OWASP-recommended pattern is httpOnly + Secure + SameSite=Strict (or Lax) cookies for the JWT, combined with a CSRF token in a header for state-changing requests. httpOnly blocks JavaScript access (defeats XSS exfiltration), Secure forces HTTPS, and SameSite limits cross-site cookie sending. For SPA + API on different origins, you may need SameSite=None; Secure plus explicit CORS allowlisting. Avoid storing long-lived refresh tokens in localStorage at all. If you must use localStorage, treat any XSS as a full account takeover and invest heavily in Content Security Policy headers.
How do refresh tokens work and why do I need them?
JWT access tokens should be short-lived (5-15 minutes) so a leaked token has limited value. But forcing users to re-login every 15 minutes is poor UX, so OAuth 2.0 introduces refresh tokens — long-lived opaque strings exchanged at the /token endpoint for new access tokens. The refresh token is typically stored in an httpOnly cookie and only sent to the auth server. Best practices: rotate refresh tokens on every use (RFC 6749bis), revoke the entire family if a token is replayed (token reuse detection), bind refresh tokens to the client (PKCE), and store them server-side hashed so a database leak doesn't expose them. Public clients (SPAs, mobile apps) should use the PKCE flow. Refresh tokens are the high-value target — protect them like passwords.
What's the difference between JWT, JWS, JWE, and JWK?
These are four related but distinct specs in the JOSE (JSON Object Signing and Encryption) family. JWS (RFC 7515) is a signed JSON structure — what people usually call a "JWT." JWE (RFC 7516) is an encrypted structure with five parts (header.encryptedKey.iv.ciphertext.tag) where the payload is hidden, not just signed. JWT (RFC 7519) is a payload format (claims) that can be wrapped in either JWS or JWE. JWK (RFC 7517) is a JSON representation of a cryptographic key, and JWKS is a set of them — typically published at /.well-known/jwks.json by identity providers. Use JWS when the payload is non-sensitive (just signed for integrity), use JWE when the payload must be confidential (e.g., contains PII). Most OAuth flows use JWS, not JWE.
What information should I avoid putting in a JWT payload?
JWT payloads are Base64URL-encoded, NOT encrypted — anyone with the token can read every claim. Never put passwords, social security numbers, credit card data, API secrets, or any PII subject to GDPR/HIPAA/PCI in a JWT payload unless you're using JWE encryption. Also avoid putting large amounts of data: every request carries the entire token in the Authorization header, so bloated payloads waste bandwidth on every API call. Keep claims to identifiers and authorization scopes (user ID, roles, expiration). For sensitive lookups, store the data server-side keyed by the sub claim. Also avoid putting mutable user data (display name, email) that may change — the cached JWT will show stale values until expiration. The token is a capability proof, not a user profile.
Key Features
- Decode JWT tokens instantly
- View header (JOSE header) with algorithm and token type
- View payload with all claims and custom data
- View signature (base64url encoded)
- Automatic detection of standard JWT claims (iss, sub, aud, exp, nbf, iat, jti)
- Human-readable timestamp formatting for date claims
- Token expiration status checker
- Support for all JWT algorithms (HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512)
- JSON syntax highlighting and formatting
- Claims information section with detailed explanations
- Copy decoded parts to clipboard
- Download decoded output
- Upload JWT files for decoding
- Dark mode support
- 100% client-side processing - tokens never leave your browser
- Works offline after initial load
- No token size limits
- Mobile-friendly responsive design
- Clear error messages for invalid tokens
- Educational information about JWT security
- No registration or login required
