Software Development

JSON Web Token and How it Works

Web authentication has evolved drastically in the last decade. The move from traditional server-rendered pages to modern, distributed frontends and API-driven architectures has created a need for stateless, scalable authentication methods that work across multiple services and platforms. Traditional server-side sessions, while functional, often struggle to scale efficiently for microservices, mobile applications, and cloud-based systems.

JSON Web Tokens (JWTs) provide a compact, secure, and self-contained solution for exchanging authentication and authorization information. By digitally signing token data, JWTs allow services to verify authenticity and integrity without relying on a centralized session store. In this article, we explore the concepts, structure, and practical use of JWTs, covering their security features, best practices, and implementation considerations for modern web applications.

1. What Is a JWT?

A JSON Web Token (JWT) is a secure, compact, and URL-safe token format used to represent claims between two parties. JWTs follow the RFC 7519 standard and are designed for stateless authentication.

A JWT is essentially:

  • A JSON object,
  • That is digitally signed, so it cannot be tampered with.
  • And may optionally be encrypted.

The primary purpose of JWTs is secure information exchange. In authentication systems, they enable users to authenticate once and then use a signed token for subsequent requests. JWTs are compact, URL-safe, self-contained, statistically verifiable, and follow industry standards, making them an excellent choice for distributed systems, particularly microservices and APIs.

2. Why Do We Need Tokens?

Authentication used to rely heavily on server-side sessions, where user data was stored in memory or databases and identified by a cookie. While functional, this model has limitations:

  • Not scalable across servers: Load-balanced apps require sticky sessions or shared caches.
  • Difficult for microservices: Multiple services need user context, requiring RPC calls to a session store.
  • Poor fit for mobile and SPA clients: Non-browser clients don’t work well with cookie-based sessions by default.
  • Centralized dependency: Everything depends on the session management server.

Why JWTs Solve These Issues

JWTs store the authentication data inside the token, so no server needs shared session memory. Each service can decode and verify the token independently. Benefits include:

  • Stateless (no server storage)
  • Easy horizontal scaling
  • Works across domains and services
  • Lightweight and fast
  • Ideal for mobile, SPA, and microservices

JWTs simplify authentication architecture by decentralizing verification and centralizing only token issuance.

3. Understanding JWT Structure: Header, Payload, Signature

A JSON Web Token (JWT) is composed of three distinct parts that work together to create a compact and secure representation of user identity and claims. These sections are known as the header, payload, and signature. Each part is encoded using Base64URL and then concatenated with periods, forming the final token string.

A JWT looks like this:

HEADER.PAYLOAD.SIGNATURE

Header

The header is a small JSON object that outlines metadata about the token. Most importantly, it specifies the type of token being used and the algorithm employed to sign it. For example:

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg defines the signing algorithm, such as HS256 (HMAC with SHA-256) or RS256 (RSA signature).
  • typ indicates that the token is a JWT.

This information allows any verifying server to know how the token was signed and how its signature should be validated.

Payload

The payload contains the actual data or claims. Claims represent statements about an entity (usually the user) and additional token metadata. JWTs support three categories of claims:

  • Registered claims: predefined, widely used properties such as:
    • sub (subject or user identifier)
    • iat (issued at time)
    • exp (expiration time)
    • iss (issuer)
    • aud (audience)
  • Public claims: custom claims that follow naming conventions and can be shared, such as:
    • role: “ADMIN”
    • permissions: [“read”, “write”]
  • Private claims: application-specific claims agreed upon between parties.

An example payload:

{
  "sub": "john",
  "role": "USER",
  "iat": 1693800000,
  "exp": 1693803600
}

Because the payload is only Base64URL encoded, not encrypted, any client can decode and view it. This is why sensitive information like passwords or secrets should never be placed inside a JWT.

Signature

The signature is the most critical part of a JWT. It ensures that the token cannot be altered without detection. After encoding the header and payload, the issuer signs them using the specified algorithm. With HS256, for example:

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

With RS256, the signature uses a private key, and verification is done using the corresponding public key. The signature guarantees:

  • Integrity: The token has not been tampered with.
  • Authenticity: The token was issued by a trusted authority.
  • Verification independence: Any service with the correct key can validate it without contacting the issuer.

4. How JWTs Maintain Trust Through Cryptographic Signatures

The security of a JSON Web Token depends on its signature, which ensures that the token has not been altered and that a trusted source issued it. When a JWT is created, the server signs the header and payload using either a shared secret key (for HMAC algorithms like HS256) or a private key (for asymmetric algorithms such as RS256 or ES256). This signature allows any receiving service to verify the token without needing to contact the issuing server.

When a client sends a JWT in a request, the server independently recomputes the signature using the expected key and compares it with the token’s signature. If they match, the token is considered authentic and untampered. If anything inside the header or payload was modified, even a single character, verification fails, and the token is rejected.

Why the Signature Matters

  • Tamper detection: If an attacker modifies the payload, the signature becomes invalid.
  • Token authenticity: Services trust the token because they trust the signing authority.
  • Decentralized validation: No need to call the auth server every time.

Algorithms

Common JWT algorithms:

AlgorithmTypeDescription
HS256HMACSimple shared-secret signing
RS256RSAPrivate key signs, public key verifies
ES256ECDSAElliptic curve, more secure and lightweight

For microservices, RS256 is preferred because verification does not require sharing secrets.

5. Common JWT Use Cases

JSON Web Tokens are widely adopted across modern software ecosystems because they offer a lightweight, stateless, and secure way to exchange identity information. Their flexibility makes them suitable for a variety of authentication and authorization scenarios. Below are some of the most common and practical use cases.

API Authentication

API authentication is the most common use case for JWTs. When a user logs into an application, the server issues a token that contains verified identity claims. Every subsequent request to the API includes this token in the Authorization header, allowing the server to authenticate the user without storing session data.

This stateless model greatly improves scalability, especially for applications that run on multiple servers or on auto-scaled cloud environments. Because each service can verify the token independently, APIs remain fast, decoupled, and easier to maintain.

Single Sign-On (SSO)

JWTs are heavily used in Single Sign-On systems due to their portability and standardized structure. An identity provider issues a JWT after authenticating a user, and that token can be consumed by multiple applications, regardless of the technology stack they use. This reduces the need for repeated logins, improves user experience, and simplifies identity management across an organization. Because JWTs are signed, each application can trust the token without needing direct communication with the identity provider.

Temporary or Time-Limited Access

JWTs are also ideal for granting temporary or restricted access to specific resources. A server can generate short-lived tokens that authorize actions such as downloading files, accessing premium content, performing administrative operations, or completing one-time transactions. Because tokens include expiration timestamps, the server can enforce strict time windows without maintaining additional state. This approach enhances security and flexibility while maintaining simplicity for both the client and server.

Microservices Authorization

In microservice architectures, JWTs simplify authorization by allowing individual services to verify user identity without relying on a centralized session store. A gateway or authentication service issues the token, and all microservices validate it using a shared secret or public key. The token can carry user roles, permissions, or tenant information, enabling fine-grained access control throughout the system. This reduces inter-service communication overhead and supports highly scalable, distributed deployments.

6. Token Storage Strategies

Choosing where to store JWTs is critical because it directly affects security, usability, and vulnerability exposure. Each storage option comes with trade-offs, and selecting the right one depends on the type of application, its threat model, and the environment it runs in.

HTTP-Only Cookies

HTTP-only cookies are considered one of the safer storage mechanisms for JWTs. Since they cannot be accessed by JavaScript, they provide strong protection against token theft through XSS attacks. The browser automatically attaches the cookie to the request, which simplifies authentication flows. With the secure, sameSite, and httpOnly flags enabled, cookies become much harder to abuse.

However, cookies are still vulnerable to Cross-Site Request Forgery (CSRF) if not configured properly. To mitigate this, developers use techniques such as sameSite=strict, double-submit cookies, CSRF tokens, or origin checks. Despite this, HTTP-only cookies remain a preferred approach for many production-grade web applications that require both convenience and enhanced security.

Local Storage (Web Applications)

Storing JWTs in the browser’s local storage is one of the simplest approaches, often used in early prototype applications or internal tools. It allows JavaScript to access the token and attach it to outgoing requests easily. However, because local storage is directly accessible to JavaScript, it becomes highly vulnerable in environments where Cross-Site Scripting (XSS) attacks are a concern. If an attacker injects malicious scripts into the page, they can immediately read or steal the stored token.

While convenient and easy to implement, local storage should be avoided for public-facing applications where user security is critical.

In-Memory Storage (SPAs and Browser Apps)

Some modern Single-Page Applications (SPAs) opt to store JWTs in memory instead of persistent browser storage. This approach significantly reduces the window of exposure because tokens disappear as soon as the user closes the browser tab. While this strategy protects against thieves who rely on long-term persistence, it can still be compromised by XSS since the token lives inside JavaScript memory.

Memory storage is often combined with short-lived access tokens and refresh tokens stored in secure HTTP-only cookies. In this hybrid model, memory storage offers reduced long-term risk, while the secure cookie provides a safe method for renewing tokens.

7. Access Token vs Refresh Token

JWT systems often use two tokens:

Access Token

An access token is a short-lived token, typically valid for about five to thirty minutes, and is included with every API request. It contains essential user claims that allow the server to verify permissions without rechecking credentials. Because it expires quickly, the impact of a potential compromise is significantly reduced, making it safer to transmit frequently in distributed systems.

Refresh Token

A refresh token lasts much longer, often for several days or weeks, and is used solely to request new access tokens when the previous one expires. It is stored securely, never sent with regular API calls, and only transmitted during token renewal flows. By keeping it isolated from routine requests and giving it an extended lifetime, applications maintain strong security while providing a smooth, continuous authentication experience.

8. Security Considerations and Token Management

While JWTs are powerful tools for authentication and authorization, improper implementation can lead to significant security risks. To maintain a secure system, developers must carefully consider token management, validation, storage, and lifecycle. Below are some key security considerations and best practices for managing JWTs effectively.

Do Not Store Sensitive Data in the Payload

JWT payloads are only Base64URL encoded, not encrypted. This means that anyone with access to the token can decode and read its contents. Never include sensitive information such as passwords, personal identification numbers, or credit card data in the payload. Instead, store sensitive data securely on the server and reference it in the token using identifiers or claims.

Always Set an Expiration

Tokens without expiration are a major security risk because they remain valid indefinitely. Always define the exp (expiration) claim to limit the lifetime of the token. Short-lived tokens minimize the impact of token theft, as they automatically become invalid after a short period. For longer user sessions, pair short-lived access tokens with refresh tokens.

Use HTTPS Exclusively

JWTs should never be transmitted over unencrypted channels. Always use HTTPS to prevent interception by attackers through man-in-the-middle (MITM) attacks. Sending tokens over plain HTTP exposes your authentication system to significant security vulnerabilities.

Rotate Secrets and Keys Regularly

Regularly updating signing keys or secrets reduces the risk of long-term token compromise. For symmetric algorithms like HS256, rotate your secret keys periodically. For asymmetric algorithms like RS256, update your private-public key pair and propagate the public key to all services that verify the token. Key rotation should be planned carefully to avoid invalidating active sessions unnecessarily.

Revoke Tokens Safely

Sometimes tokens need to be invalidated before they expire, such as after a user logs out or changes their password. Implement mechanisms such as token blacklists, versioned claims, or database tracking of invalidated tokens to ensure revoked tokens cannot be used maliciously. Proper token revocation is essential in maintaining a secure authentication system.

Limit Token Size

While JWTs are compact, large tokens can increase request size and negatively impact network performance. Only include necessary claims in the token. Avoid embedding large amounts of data, and keep the token payload focused on essential authentication and authorization information.

Use Strong Secrets

The strength of JWT security relies heavily on the secret or private key used for signing. Weak secrets are easy to brute-force and compromise. Use long, random, and complex keys for HS256, and prefer RS256 or ES256 for asymmetric signing in distributed systems where the public key can be safely shared without exposing the private key.

9. Creating and Signing JWTs

Creating a JWT involves a few key steps. First, define the claims that the token should carry, such as the user identifier (sub), issued at (iat), expiration (exp), and any custom claims like roles or permissions. These claims form the payload of the token and determine what information the token conveys.

Next, encode the header and payload using Base64URL and sign the token with a secret key or a private key, depending on the chosen algorithm. The signature ensures that the token cannot be modified without detection, providing both authenticity and integrity. Common algorithms include HS256 for symmetric signing and RS256 or ES256 for asymmetric signing.

Once generated, the JWT is returned to the client, which can store it securely and include it in the Authorization header for subsequent API requests. Short-lived tokens are recommended for access control, often paired with refresh tokens for longer sessions.

For a full practical implementation of JWT creation and authentication using Spring Boot, refer to this detailed guide: REST API Security with Spring Security JWT Token Signing.

10. Conclusion

JSON Web Tokens have become a foundational technology for modern authentication and authorization. Their compact structure, cryptographic integrity, cross-platform compatibility, and ability to support stateless authentication make them indispensable for APIs, SPAs, microservices, and mobile applications.

In this article, we explored JWTs, from their structure and decoding to signature verification, storage strategies, and best security practices. JWTs are powerful, but they must be used responsibly. When implemented with proper token lifetimes, secure storage, robust signing algorithms, and strict validation, JWTs offer one of the cleanest and most scalable approaches to API security.

This article explored JSON Web Token (JWTs) and how they are used for web authentication.

Omozegie Aziegbe

Omos Aziegbe is a technical writer and web/application developer with a BSc in Computer Science and Software Engineering from the University of Bedfordshire. Specializing in Java enterprise applications with the Jakarta EE framework, Omos also works with HTML5, CSS, and JavaScript for web development. As a freelance web developer, Omos combines technical expertise with research and writing on topics such as software engineering, programming, web application development, computer science, and technology.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button