JWT Token Encode / Decode
Quick Access to Coding Tools
Go straight to the formatter, validator, encoder, generator, or developer utility you need.
How to Use the JWT Token Encode / Decode
Paste your JWT token to decode
Paste your JWT token to decode.
Or enter header and payload to encode
Or enter header and payload to encode.
View decoded parts and verify the signature
View decoded parts and verify the signature.
JWT Encoder & Decoder — Inspect, Decode, and Create JSON Web Tokens Online
JSON Web Tokens have quietly become the backbone of modern authentication. Whether you're building a REST API that authenticates mobile clients, implementing single sign-on across multiple services, or debugging why a certain endpoint keeps returning 401 errors — you're almost certainly dealing with JWTs. They sit in the Authorization: Bearer header of every authenticated API call, they're what gets stored after a user logs in through OAuth, and they're the token format that services like Auth0, Firebase Auth, and AWS Cognito issue by default.
This tool does two things: decode any JWT you paste into it so you can read its header, payload, and verify what claims it carries — and encode a custom JWT from a JSON payload and signing secret. Both operations run entirely in your browser, which is important when you're working with tokens from live systems. Nothing gets sent to any server.
A quick decode can save you thirty minutes of guesswork. Is the token expired? Does it carry the right user ID? Was it issued by the service you expected? Is the iss claim pointing at the right authority? These are questions you can answer in seconds with a decoder rather than adding temporary log statements to your application.
The Three-Part JWT Structure — Header, Payload, Signature
Every JWT follows the same anatomy: three base64url-encoded segments separated by dots — xxxxx.yyyyy.zzzzz. Understanding what lives in each segment is the foundation of working with JWTs in any capacity.
The Header is a JSON object containing exactly two fields: typ, which is always "JWT", and alg, which names the signing algorithm. The most common algorithms you'll encounter are HS256 (HMAC with SHA-256 — symmetric, meaning the same secret both signs and verifies), RS256 (RSA with SHA-256 — asymmetric, using a private key to sign and a public key to verify), and ES256 (ECDSA with P-256 curve — also asymmetric, with smaller key sizes than RSA). The algorithm field matters enormously: it tells the verifier what to expect, and accepting the wrong algorithm is the root cause of several well-known JWT attacks.
The Payload carries the claims — structured data about the authenticated subject and the token itself. The spec defines several registered claims with well-established semantics: sub (the subject, typically a user or service ID), iss (issuer — who created this token), aud (audience — which service this token is intended for), exp (expiration — a Unix timestamp after which the token should be rejected), iat (issued at), nbf (not before — earliest time the token is valid), and jti (a unique token ID, useful for revocation lists). Beyond these, you'll often see custom claims like role, permissions, or org_id that carry application-specific data.
The Signature ties the whole thing together. It's computed by taking the encoded header and payload, concatenating them with a period, and signing the result with the algorithm and key specified in the header. This is what lets a receiving server verify two things: that the token was created by someone who holds the signing key (authenticity), and that nobody modified the header or payload after it was signed (integrity). Change a single character in the payload and the signature becomes invalid.
The point that trips up almost every developer new to JWTs: base64url encoding is not encryption. It's a reversible text encoding. Anyone with the token can decode the header and payload — no key required. Paste any JWT into the decoder on this page and you'll see the claims in plaintext immediately. The signature verifies authenticity and integrity, it does not provide confidentiality. Treat JWT payloads as public information and never put secrets like passwords, API keys, or payment details inside one.
How JWT Authentication Flows Actually Work
A typical JWT authentication sequence: the client sends credentials (username and password, an OAuth authorization code, a social login token) to the server's authentication endpoint. The server validates the credentials against its user store. If valid, the server constructs a JWT payload containing the user's ID, relevant roles or permissions, an issuer identifier, and an expiration time — then signs it and returns it to the client. From that point on, the client includes the token in the Authorization: Bearer <token> header with every API request. The receiving server decodes the token, verifies the signature, checks that the token hasn't expired, and reads the claims — all without hitting the database. That stateless verification is the fundamental advantage of JWTs over server-side session stores.
The inherent trade-off is revocation. Because the server never stores a registry of issued tokens, revoking a specific token before its natural expiration requires maintaining a blocklist of revoked jti values — which reintroduces state into a stateless system. The practical pattern that most teams settle on: very short-lived access tokens (15–60 minutes) paired with longer-lived refresh tokens (days or weeks). When the access token expires, the client uses the refresh token to obtain a fresh one. If a user logs out, is deactivated, or a security incident occurs, invalidate the refresh token — no new access tokens will be issued after the current one expires.
A common mistake: putting too much data into the JWT payload. Remember that every token is transmitted with every request, and the payload is base64url-encoded (not compressed). A token carrying a large array of permissions or a list of assigned projects adds measurable overhead to every single API call. Keep payloads lean — store references (like role IDs) rather than full objects, and fetch detailed data from the server when needed.
HS256 vs. RS256 — Choosing the Right Signing Algorithm
HS256 (HMAC-SHA256) uses a single shared secret for both signing and verification. Any service that needs to verify tokens must also have access to the signing secret. This is straightforward for a monolithic application where one server both issues and validates tokens — or a small system with two or three services that can securely share a secret through environment variables or a secrets manager. The simplicity is its strength.
RS256 (RSA-SHA256) uses asymmetric key pairs. The private key stays on the issuing service; the public key can be freely distributed to any service that needs to verify tokens. In a microservices architecture with a dedicated auth service and dozens of downstream services, RS256 means each downstream service verifies tokens independently using the published public key without ever needing access to the signing secret. Services like Auth0 and AWS Cognito use RS256 (or the equivalent ECDSA variant) precisely because the public key distribution model scales cleanly.
A practical decision rule: if your system has one authority that issues tokens and potentially many services that verify them, use RS256 or ES256. If a single service handles both issuance and verification, HS256 is simpler and performs marginally faster.
Security Vulnerabilities Every Developer Should Know
The alg: none attack: Some early JWT libraries accepted tokens where the header specified "alg": "none" — meaning "no signature required." An attacker could craft a token with any claims they wanted, set the algorithm to none, and the library would accept it as valid. This vulnerability was disclosed in 2015 and affected several major JWT implementations. Modern libraries reject alg: none by default, but if you've written your own JWT verification logic or are using an older, unmaintained library, this remains a real risk. Always use a maintained library and explicitly whitelist accepted algorithms.
Algorithm confusion: Suppose your server accepts both RS256 and HS256 tokens. An attacker takes an RS256-signed token, changes the header to claim "alg": "HS256", and signs it using your server's public key (which is, by definition, publicly known). If the server naively reads the alg field and switches to HMAC verification using the public key as the secret, the forged token passes verification. The defense: always specify the expected algorithm on the server side — never derive it from the token itself.
Missing claim validation: Verifying the signature is necessary but not sufficient. Your server must also independently validate the exp claim (reject expired tokens), the iss claim (confirm the expected issuer), and the aud claim (confirm the token is intended for your service). Skipping any of these — especially aud in a multi-service system — creates a window for token replay across services. A token issued for Service A should be rejected by Service B, even if Service B can verify the signature.
Weak signing secrets: For HS256, the security of every token depends on the strength and secrecy of the signing key. A common mistake in development is using a short or predictable secret like "secret" or "changeme" and forgetting to rotate it when moving to production. Signing keys should be cryptographically random, at least 256 bits long for HS256, and stored in a dedicated secrets manager — never committed to source code or hardcoded in configuration files.
Frequently Asked Questions About JWT
/.well-known/jwks.json endpoint), so any number of services can verify tokens without ever possessing the signing key. RS256 is strongly preferred in multi-service architectures and is the default for most third-party identity providers. ES256 provides similar asymmetric guarantees with smaller keys and faster operations on modern hardware.
jti values (requires a fast lookup store like Redis); use very short access token lifetimes (15 minutes) so the window of exposure is small, paired with a revocable refresh token; rotate the signing secret periodically (revokes all outstanding tokens at once, which is effective for emergency scenarios); or fall back to opaque reference tokens for high-security endpoints where you need instant revocation. Most production systems combine short-lived JWTs with a refresh token rotation scheme.
react-native-keychain. Never store JWTs in sessionStorage (vulnerable to XSS, with none of the CSRF protection benefits of cookies) or in regular non-HttpOnly cookies (accessible to JavaScript, defeating the purpose).
"alg": "none" in the header caused the library to skip signature verification entirely. An attacker could set any claims they wanted, set the algorithm to "none," and the library would accept the token as valid — effectively forging authentication credentials out of thin air. This vulnerability affected the Java jwt-auth, node-jsonwebtoken, and several other libraries before it was patched. It remains a risk in custom JWT handling code and abandoned libraries. The defense: use a well-maintained, actively updated JWT library, explicitly specify the expected algorithm(s) on the server, and never accept whatever algorithm the token header claims.
exp — never issue a token with no expiration at all. The exp claim should always be present, and your verification logic should always check it.