JWT Encoder & Decoder

🇬🇧English
🇪🇸Español
🇫🇷Français
🇩🇪Deutsch
🇨🇳中文
🇯🇵日本語
🇮🇳हिन्दी
🇸🇦العربية
🇵🇹Português
🇷🇺Русский
🇧🇩বাংলা
🇮🇩Bahasa
🇹🇷Türkçe
🇵🇱Polski
🇻🇳Tiếng Việt
🇵🇰اردو

Introduction to JSON Web Tokens

A complete guide to understanding JWTs — what they are, how they work, when to use them, and how encoding, decoding, validation, and verification differ.

What is JSON Web Token?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.

JWTs can be signed using a secret with the HMAC algorithm, or a public/private key pair using RSA or ECDSA.

Although JWTs can be encrypted to also provide secrecy between parties, the most common use case focuses on signed tokens. Signed tokens can verify the integrity of the claims contained within them, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.

Open standard: JWT is defined in RFC 7519 published by the Internet Engineering Task Force (IETF). It is widely adopted across platforms, languages, and frameworks, making it a safe interoperability choice for authentication and information exchange.

When should you use JSON Web Tokens?

Here are the most common scenarios where JSON Web Tokens are the right tool:

What is the JSON Web Token structure?

In its compact form, JSON Web Tokens consist of three parts separated by dots (.):

A JWT therefore looks like this:

xxxxx.yyyyy.zzzzz

The header typically consists of two parts: the type of the token (which is JWT) and the signing algorithm being used, such as HMAC SHA256 or RSA.

JSON — Header example{ "alg": "HS256", "typ": "JWT" }

This JSON is then Base64Url encoded to form the first part of the JWT.

Payload

The second part is the payload, which contains the claims. Claims are statements about an entity (typically the user) and additional metadata. There are three types of claims:

JSON — Payload example{ "sub": "1234567890", "name": "John Doe", "admin": true, "iat": 1516239022 }

The payload is then Base64Url encoded to form the second part of the JWT.

Important: For signed tokens, the payload is Base64Url encoded — not encrypted. Anyone who obtains the token can read its contents. Do not put secret information in the payload or header unless the token is encrypted (JWE).

Signature

To create the signature, you take the encoded header, the encoded payload, a secret, and the algorithm specified in the header, and sign that.

For example, using the HMAC SHA256 algorithm:

Pseudocode — Signature creationHMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )

The signature verifies that the message was not altered in transit. When the token is signed with a private key, it also proves that the sender is who they claim to be.

Putting it all together, the output is three Base64Url strings separated by dots — compact enough to be passed in an HTTP header or URL parameter. Here is a real encoded JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

You can paste this token directly into our JWT Encoder & Decoder to inspect it, or experiment with the jwt.io Debugger.

How do JSON Web Tokens work?

In authentication, when the user successfully logs in using their credentials, a JSON Web Token is returned by the server. Since tokens are credentials, great care must be taken to prevent security issues. In general, you should not keep tokens longer than required.

Whenever the user wants to access a protected route or resource, the user agent should send the JWT — typically in the Authorization header using the Bearer schema:

HTTP HeaderAuthorization: Bearer <token>

This is a stateless authorization mechanism. The server's protected routes check for a valid JWT in the Authorization header. If the token is valid, the user is allowed to access protected resources. Because the token carries all the claims, the server may not need to query a database for certain operations.

CORS and JWTs: When JWTs are sent in the Authorization header, Cross-Origin Resource Sharing (CORS) won't be an issue because the request does not rely on cookies. However, be mindful of header size limits — some servers reject requests with headers larger than 8 KB. Avoid embedding large permission sets in tokens; consider using fine-grained authorization solutions for complex permission models.

A typical JWT authentication flow works as follows:

  1. The client sends credentials (username + password) to the Authorization Server.
  2. The Authorization Server validates the credentials and issues a JWT access token (and optionally a refresh token).
  3. The client stores the token (e.g., in memory or a secure cookie) and attaches it to subsequent API requests via the Authorization: Bearer header.
  4. The Resource Server (API) validates the JWT signature, checks claims (exp, aud, iss), and grants or denies access.
  5. The token eventually expires (exp claim) and the client must re-authenticate or use a refresh token.
Storage warning: Do not store JWTs in localStorage if the token grants sensitive permissions — it is accessible by any JavaScript on the page and is therefore vulnerable to XSS attacks. For highly sensitive applications, prefer HttpOnly cookies.

Why should we use JSON Web Tokens?

Let's compare JWTs against two older alternatives:

FeatureJWTSWTSAML
FormatJSON (compact)Form-encoded key-value pairsXML (verbose)
SizeSmall — good for HTTP headers & URLsSmallLarge — not suitable for HTTP headers
SigningSymmetric (HMAC) or asymmetric (RSA, ECDSA)Symmetric (HMAC) onlySymmetric or asymmetric (XML DSig — complex)
ParsingNative in all languages via JSON parsersSimple key-value parsingRequires an XML parser; no natural object mapping
Web & mobileExcellent — widely supported at internet scaleLimited adoptionCommon in enterprise SSO; heavy for mobile
StandardRFC 7519InformalOASIS SAML

Because JSON is less verbose than XML, an encoded JWT is significantly smaller than a comparable SAML assertion. JSON parsers are native to virtually all programming languages, while XML requires a dedicated parser with no natural document-to-object mapping. These properties make JWT the default choice for modern web and mobile applications.

Difference Between Validating and Verifying a JWT

JWT validation and verification are often used interchangeably, but they address slightly different aspects of JWT security:

ValidationVerification
What it checksStructure, format, and claim valuesAuthenticity and integrity via cryptographic signature
Key questionsIs this token well-formed? Are the claims correct?Was this token really issued by a trusted party? Has it been tampered with?
Requires a key?NoYes — a shared secret (HMAC) or public key (RSA/ECDSA)

JWT Validation

Validation generally refers to checking the structure, format, and content of the JWT:

JWT Verification

Verification confirms the authenticity and integrity of the token:

In practice: Most JWT libraries (such as jsonwebtoken for Node.js, PyJWT for Python, golang-jwt for Go) combine both steps when you call their verify() function. Always use a library's built-in verify method rather than manually decoding and skipping signature verification.

Difference Between Encoding and Decoding a JWT

Encoding a JWT

Encoding transforms a header and payload into the compact, URL-safe JWT string:

  1. Serialize the header object to JSON, then Base64Url encode it.
  2. Serialize the payload object to JSON, then Base64Url encode it.
  3. Concatenate the two encoded strings with a dot: encodedHeader.encodedPayload.
  4. Sign this string using the algorithm specified in the header (e.g., HMAC-SHA256 with a secret key, or RSA-SHA256 with a private key).
  5. Base64Url encode the resulting binary signature.
  6. Concatenate everything: encodedHeader.encodedPayload.encodedSignature.
Pseudocode — JWT Encodingheader = base64UrlEncode(JSON.stringify({ alg: "HS256", typ: "JWT" })) payload = base64UrlEncode(JSON.stringify({ sub: "1234567890", name: "John Doe" })) signature = base64UrlEncode(HMACSHA256(header + "." + payload, secret)) jwt = header + "." + payload + "." + signature

Decoding a JWT

Decoding reverses the encoding process. It converts each Base64Url-encoded segment back into readable JSON. Decoding does not require any key — anyone who holds the token can decode the header and payload. This is why you must never store sensitive data in a JWT payload unless the token is also encrypted.

In many JWT libraries, "decoding" also implies verification: after decoding, the library re-computes the expected signature and compares it against the token's signature to confirm authenticity.

Pseudocode — JWT Decoding[encodedHeader, encodedPayload, encodedSignature] = jwt.split(".") header = JSON.parse(base64UrlDecode(encodedHeader)) payload = JSON.parse(base64UrlDecode(encodedPayload)) // Verification (optional but recommended) expected = base64UrlEncode(HMACSHA256(encodedHeader + "." + encodedPayload, secret)) isValid = (expected === encodedSignature)
EncodingDecoding
InputHeader object + payload object + signing keyJWT string (+ optional signing key for verification)
OutputCompact JWT string (xxx.yyy.zzz)Readable header & payload JSON (+ validity status)
Requires key?Yes — to sign the tokenNo to read; yes to verify authenticity
Hides content?No — Base64Url is not encryptionN/A — content was never hidden
Try it now: Use our JWT Encoder & Decoder tool to encode a custom payload and see the resulting token, or paste any JWT to instantly decode and verify it — all processing happens locally in your browser with Web Crypto API. No data is sent to any server.

Ready to work with JWTs?

Use our free, privacy-first JWT tool to encode, decode, and verify tokens instantly — no data leaves your browser.

Open JWT Encoder & Decoder