If you have ever logged into a web application, there is a good chance a JWT was involved behind the scenes. JSON Web Tokens have become the standard way to handle authentication in modern web and mobile apps, yet many developers use them without fully understanding what they are or how they work. This guide breaks JWT down into plain language, walks through the three parts of every token, explains signing and verification, and shows you how to decode JWTs for free.
What Is a JWT?
A JSON Web Token (JWT, pronounced "jot") is a compact, URL-safe string that carries a set of claims between two parties. It is defined by RFC 7519 and is most commonly used for authentication and information exchange.
The key idea is self-containment. A JWT carries all the information needed to verify the user and their permissions directly inside the token itself. The server does not need to look up a session in a database on every request because everything it needs is embedded in the token and cryptographically signed to prevent tampering.
A JWT looks like this:
<code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c</code>
Those three sections separated by dots are the header, payload, and signature.
The Three Parts of a JWT
<strong>1. Header.</strong> The header is a Base64URL-encoded JSON object that describes the token type and the signing algorithm. A typical header looks like <code>{"alg": "HS256", "typ": "JWT"}</code>. The <code>alg</code> field tells the server which algorithm to use when verifying the signature.
<strong>2. Payload.</strong> The payload is also a Base64URL-encoded JSON object containing the claims. Claims are statements about the user and metadata. Standard claims include <code>sub</code> (subject, usually a user ID), <code>iat</code> (issued at), <code>exp</code> (expiration time), and <code>iss</code> (issuer). You can also add custom claims like <code>role</code> or <code>email</code>.
<strong>3. Signature.</strong> The signature is created by taking the encoded header, the encoded payload, a secret key, and the algorithm specified in the header, then running them through the signing function. For HMAC SHA-256, the formula is: <code>HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)</code>.
The signature ensures that the token has not been altered. If anyone changes a single character in the header or payload, the signature will no longer match, and the server will reject the token.
How JWT Authentication Works
A typical JWT authentication flow has four steps:
1. The user sends their credentials (username and password) to the server. 2. The server verifies the credentials and generates a JWT containing the user ID, permissions, and an expiration time. It signs the token with a secret key. 3. The server sends the JWT back to the client. The client stores it, usually in memory or an HTTP-only cookie. 4. On every subsequent request, the client sends the JWT in the Authorization header as <code>Bearer <token></code>. The server verifies the signature and reads the claims without hitting the database.
This stateless approach scales well because any server instance can verify the token independently. There is no shared session store to manage or synchronize across servers.
How to Decode a JWT
Because the header and payload are simply Base64URL-encoded (not encrypted), anyone can decode them and read the contents. This is by design: JWTs are signed, not secret.
To decode a JWT instantly, use the free <a href="/tools/jwt-decoder">JWT Decoder</a> on ToolboxHub:
1. Open <a href="/tools/jwt-decoder">/tools/jwt-decoder</a>. 2. Paste the full JWT string into the input field. 3. The tool immediately displays the decoded header and payload as formatted JSON, along with information about the signing algorithm and expiration.
This is invaluable for debugging authentication issues. You can quickly check whether a token has expired, what claims it contains, and which algorithm was used to sign it. The tool runs entirely in your browser, so sensitive tokens never leave your device.
Common JWT Security Mistakes
JWTs are secure when used correctly, but several common mistakes can create serious vulnerabilities:
- <strong>Storing tokens in localStorage:</strong> LocalStorage is accessible to any JavaScript running on the page, making tokens vulnerable to XSS attacks. Prefer HTTP-only cookies with the Secure and SameSite flags. - <strong>Not validating the algorithm:</strong> An attacker can change the header to <code>"alg": "none"</code> and strip the signature. Always validate the algorithm server-side and reject unexpected values. - <strong>Using weak secrets:</strong> HMAC-based JWTs are only as strong as the secret key. Use a cryptographically random string of at least 256 bits. Never use short, guessable passwords. - <strong>Ignoring expiration:</strong> Always set the <code>exp</code> claim and enforce it. Long-lived tokens give attackers a larger window if a token is stolen. - <strong>Putting sensitive data in the payload:</strong> Remember that the payload is not encrypted. Do not include passwords, credit card numbers, or other secrets in JWT claims.
JWT vs. Session-Based Authentication
Session-based authentication stores session data on the server and sends only a session ID to the client as a cookie. JWT-based authentication stores the session data inside the token itself.
JWTs are preferred for stateless APIs, microservices architectures, and mobile apps because they eliminate the need for a centralized session store. Sessions are preferred when you need the ability to immediately revoke access, because invalidating a JWT before it expires requires extra infrastructure like a token blacklist.
Many production systems use a hybrid approach: short-lived JWTs for access (5 to 15 minutes) combined with longer-lived refresh tokens stored securely on the server. This balances the scalability of JWTs with the revocation capabilities of server-side sessions.
Decode Your JWT Now
Need to inspect a JWT from an API response or debug an authentication issue? Use the free <a href="/tools/jwt-decoder">ToolboxHub JWT Decoder</a> to instantly see the header, payload, and expiration. You might also find the <a href="/tools/json-formatter">JSON Formatter</a> helpful for reading the decoded payload, or the <a href="/tools/base64">Base64 Encoder/Decoder</a> for understanding the encoding that JWTs use under the hood.