JWT Tokens: The Complete Guide to JSON Web Tokens and How to Decode Them
JSON Web Tokens (JWTs) have become the dominant standard for transmitting authenticated information between parties in web applications. A JWT is a compact, URL-safe string that encodes a set of claims (name-value pairs) as a JSON object. These claims can include user identity, permissions, expiration times, and any custom data your application needs. JWTs are widely used for authentication, authorization, information exchange, and session management in modern web applications, APIs, and microservices architectures.
The power of JWTs lies in their self-contained nature. Unlike session-based authentication that requires server-side storage, a JWT carries all the necessary information within the token itself. The server can verify the token's authenticity by checking its signature, without needing to query a database or session store. This makes JWTs ideal for distributed systems, microservices, and stateless API architectures where minimizing server-side state is a priority.
Our JWT Decoder tool lets you instantly inspect any JWT token by decoding its header and payload into readable JSON. You can see the algorithm used, check expiration times, verify registered claims, and examine custom data — all without writing code or installing anything. The tool also automatically checks whether the token has expired and displays the expiration status prominently, helping you quickly diagnose authentication issues.
JWT Structure: Header.Payload.Signature
A JWT consists of three parts separated by dots: the header, the payload, and the signature. Each part is Base64URL-encoded (a URL-safe variant of Base64 that replaces + with - and / with _). The standard format is "xxxxx.yyyyy.zzzzz", where xxxxx is the encoded header, yyyyy is the encoded payload, and zzzzz is the encoded signature. Understanding this three-part structure is the foundation for working with JWTs effectively.
The three components of a JWT:
Header (xxxxx): A JSON object containing metadata about the token, typically the signing algorithm (alg) and token type (typ). For example: {"alg": "HS256", "typ": "JWT"}. This tells the recipient how the signature was generated and what kind of token this is.
Payload (yyyyy): A JSON object containing the claims — the actual data being transmitted. Claims can be registered (standard fields like iss, sub, aud, exp), public (defined by applications), or private (custom key-value pairs for your specific use case).
Signature (zzzzz): The signature is created by taking the encoded header, the encoded payload, a secret key (for HMAC algorithms) or a private key (for RSA/ECDSA algorithms), and signing them using the algorithm specified in the header. The signature ensures the token hasn't been tampered with.
It is critical to understand that the header and payload of a JWT are only Base64URL-encoded, not encrypted. This means anyone with access to the token can decode and read its contents — our decoder tool does exactly this. The signature provides integrity verification (ensuring the token hasn't been modified), not confidentiality. If you need to keep the payload contents secret, you must use JWT encryption (JWE) in addition to or instead of JWT signing (JWS).
JWT Header Fields and Signing Algorithms
The JWT header is a JSON object that tells the recipient how to process and verify the token. While it can contain custom fields, two headers are almost universally present: "alg" (algorithm) and "typ" (type). The algorithm specified in the header determines how the signature was generated and how it should be verified, making it one of the most security-critical parts of the entire token.
Common Algorithms
- • HS256 — HMAC with SHA-256 (symmetric, shared secret)
- • HS384 — HMAC with SHA-384
- • HS512 — HMAC with SHA-512
- • RS256 — RSA Signature with SHA-256 (asymmetric)
- • RS384 — RSA Signature with SHA-384
- • RS512 — RSA Signature with SHA-512
- • ES256 — ECDSA with SHA-256 (elliptic curve)
- • PS256 — RSA-PSS with SHA-256
Header Fields
- • alg — Signing algorithm (required)
- • typ — Token type, usually "JWT"
- • cty — Content type (for nested JWTs)
- • kid — Key ID for key rotation
- • jku — JWK Set URL for public key
- • x5u — X.509 certificate URL
JWT Payload Claims and Standard Fields
The payload contains the actual data carried by the token in the form of claims — name-value pairs that convey information about the authentication context, the subject, and any custom data your application needs. The JWT specification defines several registered claims with standardized meanings, and applications can add their own custom claims for any purpose.
Standard registered claims:
- iss (Issuer): Identifies the principal that issued the JWT. Typically a URL or identifier for the authentication service. Verifying the issuer ensures the token came from a trusted source.
- sub (Subject): Identifies the principal that is the subject of the JWT. Usually the user ID or unique identifier of the authenticated entity. This is the most commonly used claim for identifying who the token represents.
- aud (Audience): Identifies the recipients that the JWT is intended for. A token issued for one API should not be accepted by a different API. Audience validation prevents cross-service token reuse.
- exp (Expiration Time): The time after which the JWT must not be accepted. Our decoder automatically checks this field and displays whether the token is currently valid or expired.
- iat (Issued At): The time at which the JWT was issued. Useful for determining token age and implementing token rotation policies.
- nbf (Not Before): The time before which the JWT must not be accepted. Allows issuing tokens that become valid at a future time.
- jti (JWT ID): A unique identifier for the JWT. Used to prevent token replay attacks by tracking which token IDs have already been used.
JWT Signature and Verification
The signature is what makes a JWT trustworthy. It provides cryptographic assurance that the token's header and payload have not been modified since the token was issued. Without signature verification, a JWT is just an untrusted piece of Base64-encoded data that anyone could forge. Understanding how signatures work is essential for implementing secure authentication systems and for knowing what our decoder can and cannot tell you about a token's authenticity.
How signature verification works:
HMAC signatures (HS256, HS384, HS512): The signature is computed using a shared secret key. Both the issuer and the verifier must possess the same secret key. The signature is created by computing HMAC-SHA256(Base64URL(header) + "." + Base64URL(payload), secret). To verify, the recipient recomputes the HMAC with the shared secret and compares it to the token's signature.
RSA signatures (RS256, RS384, RS512): The issuer signs with a private key, and the verifier checks the signature with the corresponding public key. This allows the public key to be freely distributed for verification without compromising the signing capability, making it ideal for third-party token verification.
ECDSA signatures (ES256, ES384, ES512): Similar to RSA but uses elliptic curve cryptography, providing equivalent security with shorter keys and signatures. ECDSA is increasingly popular for JWT signing due to its efficiency.
Important: Our JWT decoder can decode and display the header and payload of any JWT, but it cannot verify signatures because it does not have access to the signing key. A decoded JWT that appears to contain valid claims may still be forged if the signature is invalid. Always verify JWT signatures in your server-side code before trusting the claims.
JWT Security Best Practices
JWTs are powerful but can introduce serious security vulnerabilities when used incorrectly. The self-contained nature of JWTs means that a compromised or improperly validated token can grant unauthorized access to your system. Following established security best practices is essential for using JWTs safely in production environments.
Do This
- • Always verify the signature before trusting claims
- • Validate the exp claim to reject expired tokens
- • Check the iss claim against your trusted issuers
- • Verify the aud claim matches your service
- • Use short expiration times (15-60 minutes)
- • Store tokens securely (HttpOnly cookies preferred)
- • Use strong algorithms (RS256, ES256 over HS256)
Avoid This
- • Never accept tokens without signature verification
- • Don't store sensitive data in the payload (it's readable)
- • Don't use the alg:"none" attack vector
- • Don't store tokens in localStorage (XSS vulnerable)
- • Don't use long-lived tokens without refresh mechanisms
- • Don't reuse the same signing key across services
- • Don't ignore the nbf and aud claims during validation
Common JWT Pitfalls and How to Avoid Them
Despite their apparent simplicity, JWTs have several well-documented security pitfalls that continue to trip up developers. These issues range from subtle algorithm confusion attacks to straightforward implementation mistakes. Being aware of these common pitfalls helps you build more secure authentication systems and avoid vulnerabilities that could compromise your application.
Critical pitfalls to watch for:
- Algorithm confusion attack: If your server accepts both HMAC and RSA algorithms, an attacker could change the alg header from RS256 to HS256 and use the public key as the HMAC secret. Always explicitly specify which algorithms your server accepts.
- The "none" algorithm: Some JWT libraries accept alg:"none", which means the token has no signature. Always reject tokens with the none algorithm in production.
- Token revocation: JWTs cannot be easily revoked once issued. If a user logs out or their access is revoked, the JWT remains valid until it expires. Implement a token blacklist or use short-lived tokens with refresh tokens.
- Sensitive data in payload: The payload is Base64-encoded, not encrypted. Anyone who intercepts the token can read its contents. Never include passwords, social security numbers, or other sensitive data in JWT claims.
- Key management: If you use HMAC with a shared secret and that secret is compromised, an attacker can forge valid tokens for your entire system. Rotate signing keys regularly and use asymmetric algorithms for multi-service architectures.