The Anatomy of JSON Web Tokens (JWT): What They Are and How They Work

The Anatomy of JSON Web Tokens (JWT): What They Are and How They Work

In modern web development, secure and scalable authentication is paramount. As applications moved away from monolithic architectures toward microservices and decentralized APIs, traditional session-based authentication hit a scaling wall. Enter the JSON Web Token (JWT).

Whether building a Single Page Application (SPA), a mobile app, or managing inter-service communication, understanding JWTs is essential. This comprehensive guide breaks down what JWTs are, how they function, their internal structure, and the architectural concepts surrounding their security.


What is a JSON Web Token (JWT)?

A 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.

Because this information is digitally signed, it can be verified and trusted. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

Why are JWTs utilized?

The primary use case for JWTs is Authentication and Stateless Information Exchange. Once a user authenticates, subsequent requests include the JWT, allowing the application to verify permissions and grant access to protected routes, services, and resources based on the token's contents.

The Concept of Bearer Tokens

In web communication, JWTs are most frequently utilized as Bearer Tokens. The term "Bearer" originates from the OAuth 2.0 framework (RFC 6750) and signifies that the bearer of the token—meaning whichever entity possesses the string—is granted access to the associated resources.

Architecturally, a Bearer token acts like a cash voucher or a physical key: the system validating it does not verify who is holding it, but rather if the token itself is authentic and valid. In standard implementations, the client transmits the JWT inside the HTTP requests using the Authorization header with the Bearer schema prefix:

Authorization: Bearer xxxxx.yyyyy.zzzzz

Session-Based vs. Token-Based Authentication

To understand the mechanics of JWTs, it helps to analyze how they contrast with traditional authentication systems.

1. Traditional Session-Based Authentication (Stateful)

  • The user enters their credentials.
  • The server verifies the credentials and creates a session record in a database or a memory cache (such as Redis).
  • The server sends a cookie containing a unique Session ID back to the browser.
  • On subsequent requests, the browser automatically sends the cookie, and the server queries its storage to match the Session ID and verify the identity.

Characteristics: As applications scale horizontally across multiple servers, maintaining and syncing session states across decentralized infrastructure introduces architectural complexity and resource overhead.

2. JWT Token-Based Authentication (Stateless)

  • The user authenticates successfully.
  • The server generates a signed JWT containing user metadata and specific claims, then transmits it back to the client without saving any record on the backend.
  • The client stores the token locally and attaches it to future requests.
  • The receiving server validates the cryptographic signature of the token. If the signature matches and the conditions are met, the request is authorized.

Characteristics: This model is entirely stateless. Any backend server possessing the correct verification keys can evaluate the token independently without querying a centralized session database.

Anatomy of a JWT: The Three Components

A JWT is visually represented as three string segments separated by dots (.).

xxxxx.yyyyy.zzzzz

Each part is independently encoded using Base64URL. When decomposed, these three parts represent distinct cryptographic compartments:

  1. The Header
  2. The Payload
  3. The Signature

1. The Header

The header contains structural metadata about the token. It typically identifies the token type (JWT) and the specific signing algorithm being applied, such as HS256 (HMAC using SHA-256) or RS256 (RSA using SHA-256).

{
  "alg": "HS256",
  "typ": "JWT"
}

2. The Payload

The payload houses the claims, which are statements about the entity (the user) and additional contextual metadata. Standard specifications define three categories of claims: registered, public, and private.

  • iss (Issuer): Identifies the authority that issued the token.
  • sub (Subject): The unique identifier of the user or client.
  • aud (Audience): The intended recipients or services meant to process the token.
  • exp (Expiration Time): The exact Unix timestamp defining when the token ceases to be valid.
  • iat (Issued At): The timestamp marking when the token was generated.
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1715682220,
  "exp": 1715685820
}

3. The Signature

The signature is the component that ensures data integrity. It is generated by taking the encoded header, the encoded payload, a cryptographic key, and processing them through the algorithm specified in the header.

For instance, under an HMAC SHA256 configuration, the mathematical composition follows this structure:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secretKey
)

The signature allows the verifying system to confirm that the token was generated by a trusted source and has not undergone any modification during transit.

Frequently Asked Questions (FAQ) About JWT

Are JWTs encrypted? Can anyone read the payload data?

Standard JWTs are signed to guarantee integrity, but they are not encrypted. Because Base64URL encoding is a reversible formatting process and not an encryption mechanism, anyone who intercepts a token can decode it to view the payload claims in plain text. For this reason, architectures generally exclude sensitive parameters like passwords or confidential personal data from the token payload.

Note: If you need to evaluate the contents of an access token or audit its claims, the nKode JWT Decoder & Inspector provides local-only decoding to parse headers, payload claims, and temporal validity without transmitting data to external servers.

How are JWTs stored within a browser environment?

Web applications generally utilize two primary storage strategies, each presenting different security trade-offs:

  1. Web Storage (LocalStorage / SessionStorage): Accessible via client-side JavaScript, making it straightforward to manage, but vulnerable if the application suffers from Cross-Site Scripting (XSS) vulnerabilities, as malicious scripts can extract the strings.
  2. HttpOnly Cookies: Automatically appended to outgoing HTTP requests by the browser. Because JavaScript cannot access cookies configured with the HttpOnly attribute, they are isolated from XSS attacks, though the architecture must account for mitigation against Cross-Site Request Forgery (CSRF).

How does token revocation operate in stateless systems?

Due to the stateless nature of JWTs, an issued token remains technically valid until the timestamp in its exp claim is reached. Overriding this behavior prematurely requires implementing hybrid backend mechanics:

  • Blacklisting Systems: Upon logout, the token's unique identifier (jti) is stored in a high-speed, in-memory database (such as Redis). This record is maintained only for the token's remaining lifespan (TTL). The backend checks every incoming request against this list, immediately rejecting any tokens that have been blacklisted.
  • Access & Refresh Tokens (Hybrid Model): The application issues a short-lived Access Token (JWT), typically lasting 15 minutes, for routine data transfers, alongside a long-lived Refresh Token stored on the backend. To revoke access prematurely, the backend invalidates the Refresh Token in the database. Consequently, the user is permanently locked out as soon as the current short-lived Access Token expires.

What is the "Algorithm Confusion" vulnerability and how does it relate to Heuristics?

Algorithm Confusion is a classic logical flaw in how certain backend applications verify tokens. The fundamental difference between cryptographic methods lies in key usage: asymmetric algorithms (like RS256) require a private key to sign and a public key to verify, whereas symmetric algorithms (like HS256) utilize the exact same shared secret for both operations.

The vulnerability occurs when an attacker modifies the header of a valid token from RS256 to HS256, and signs it using the application's public key (which is, by definition, publicly accessible). If the backend validation logic is loosely configured and blindly trusts the token's header, it will read "HS256", retrieve its stored public key, and incorrectly treat it as the HMAC shared secret. As a result, the forged token is validated successfully, leading to an authentication bypass.

The Role of Heuristics: Because these exploits rely on unexpected structural anomalies within the token, modern engineering practices emphasize static analysis. Tools like the JWT Decoder & Inspector run passive heuristic checks on the parsed token, providing real-time alerts if the combination of algorithms, headers, or internal structure exhibits unusual or high-risk patterns.

Key Architectural Considerations

Robust JWT implementations typically adhere to several architectural patterns:

  • Strict validation of the temporal claims (exp, nbf, iat) during every verification cycle.
  • Enforcement of strict cryptographic requirements, ensuring that HS256 keys possess adequate entropy to withstand brute-force analysis.
  • Explicit whitelisting of accepted algorithms within the backend parsing configuration to neutralize alg: "none" or unexpected key-matching logic.
  • Minimizing payload density to keep HTTP header sizes optimized for network performance.

Read Also

What is Base64 and How Does It Work
What is Base64 and How Does It Work
TokenToolkit.js: Client-Side JavaScript Library for JWT, Base64, URL & Hashing
TokenToolkit.js: Client-Side JavaScript Library for JWT, Base64, URL & Hashing
The Anatomy of a UUID: Understanding Unique Identifiers
The Anatomy of a UUID: Understanding Unique Identifiers