JSON Web Token (JWT): A Complete Guide to JSON Web Tokens

JWT is commonly associated with authentication and authorization, but its capabilities extend beyond simply logging users into applications. It can be used to securely communicate identity information, permissions, session-related data, and other claims between different systems.

JWT Logo
JWT Logo

JSON Web Token, commonly known as JWT, has become one of the most widely used standards for securely transmitting information between applications, APIs, services, and users. JWT is particularly popular in modern web applications because it provides a compact way to represent claims between two parties and can be easily transmitted through HTTP headers, URLs, cookies, and other mechanisms.

JWT is commonly associated with authentication and authorization, but its capabilities extend beyond simply logging users into applications. It can be used to securely communicate identity information, permissions, session-related data, and other claims between different systems.

This comprehensive guide explains what JWT is, where it came from, how it works, its structure, encoding and signing process, encryption, verification, authentication flow, practical examples, security considerations, advantages, disadvantages, and common mistakes.

What Is JWT?

JWT stands for JSON Web Token.

It is a compact, URL-safe format used to represent claims that can be transferred between two parties. These claims are represented as a JSON object and are typically digitally signed so that the recipient can verify that the information has not been modified.

A JWT usually looks like this:

xxxxx.yyyyy.zzzzz

It contains three components:

Header.Payload.Signature

For example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTYiLCJuYW1lIjoiTm9tYW4iLCJpYXQiOjE3MjAwMDAwMDB9.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

These three sections are:

  1. Header
  2. Payload
  3. Signature

One important point is often misunderstood:

A normal JWT is encoded and signed, not encrypted.

Anyone who obtains a normal JWT can decode its header and payload. The signature prevents unauthorized modification, but it does not hide the contents.

Origin and History of JWT

JWT is not an isolated technology. It belongs to a broader family of Internet standards developed around JSON-based security and identity information.

JWT was standardized by the Internet Engineering Task Force (IETF) through the JSON Web Token (JWT) specification, RFC 7519. RFC 7519 was published in May 2015.

JWT was designed as part of a group of specifications collectively known as JOSE — JSON Object Signing and

Encryption.

The JOSE family includes several important standards:

  • JWS — JSON Web Signature
  • JWE — JSON Web Encryption
  • JWK — JSON Web Key
  • JWA — JSON Web Algorithms
  • JWT — JSON Web Token

JWT itself defines how claims are represented, while other JOSE specifications define how those claims can be digitally signed or encrypted.

JWT became particularly popular as web development moved toward:

  • REST APIs
  • Single-page applications
  • Mobile applications
  • Microservices
  • Cloud applications
  • Distributed systems
  • OAuth 2.0 and OpenID Connect

Before JWT became common, applications frequently relied on traditional server-side sessions. Those sessions remain useful, but JWT introduced a convenient token-based approach that works particularly well across distributed systems.

Why Was JWT Created?

Traditional authentication often works like this:

  1. User logs in.
  2. Server verifies username and password.
  3. Server creates a session.
  4. Session information is stored on the server.
  5. Browser receives a session identifier.
  6. Browser sends that identifier with future requests.
  7. Server looks up the session.

This works well, but maintaining sessions across many servers can introduce additional infrastructure requirements.

For example, suppose an application has:

Server A
Server B
Server C

If the user logs in through Server A but the next request goes to Server C, Server C needs access to the session information.

This can be solved using shared session storage such as Redis or a database, but it introduces additional infrastructure.

JWT provides another approach.

Instead of storing all authentication information in a server-side session, the server can issue a signed token containing relevant claims.

The client then sends the token with subsequent requests.

Understanding the Three Parts of JWT

A JWT consists of three Base64URL-encoded components separated by periods.

Header.Payload.Signature

Let's examine each part.

1. Header

The header contains information about the token itself.

A typical header looks like:

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

The two common properties are:

alg

alg specifies the cryptographic algorithm.

For example:

HS256

means HMAC using SHA-256.

Other algorithms include:

RS256
RS512
ES256
PS256

typ

typ identifies the token type.

For JWT it is commonly:

JWT

The header is then Base64URL encoded.

2. Payload

The payload contains the claims.

For example:

{
  "sub": "123456",
  "name": "Muhammad Noman",
  "role": "admin",
  "iat": 1720000000,
  "exp": 1720003600
}

Claims can describe information such as:

  • User ID
  • Username
  • Role
  • Permissions
  • Token issuer
  • Token audience
  • Token creation time
  • Expiration time

JWT defines several registered claim names.

Important claims include:

iss — Issuer

Identifies who issued the token.

"iss": "https://example.com"

sub — Subject

Identifies the subject of the token.

For authentication, this is commonly a user identifier.

"sub": "123456"

aud — Audience

Identifies the intended recipient of the token.

"aud": "api.example.com"

exp — Expiration Time

Specifies when the token expires.

"exp": 1720003600

iat — Issued At

Indicates when the token was issued.

"iat": 1719990000

nbf — Not Before

Specifies the time before which the token must not be accepted.

"nbf": 1720000000

jti — JWT ID

Provides a unique identifier for the token.

"jti": "8f14e45f-ea..."

Applications can also define custom claims.

For example:

{
  "sub": "123456",
  "role": "manager",
  "department": "finance"
}

However, sensitive information should not normally be placed in a standard signed JWT because its payload is readable.

3. Signature

The signature is what allows the recipient to detect unauthorized modifications.

For an HMAC-based JWT, conceptually:

HMACSHA256(
    Base64URL(Header) + "." + Base64URL(Payload),
    SecretKey
)

The resulting signature is encoded and appended to the token.

Therefore:

JWT =
Base64URL(Header)
+
"."
+
Base64URL(Payload)
+
"."
+
Base64URL(Signature)

If somebody changes the payload, the signature no longer matches.

Encoding vs Encryption

This is one of the most important JWT concepts.

JWT commonly uses Base64URL encoding.

Encoding is not encryption.

For example:

{
  "name": "Noman"
}

can be Base64URL encoded into a string.

Anyone can decode it.

There is no secret required to decode Base64URL.

Therefore, do not put information such as:

Password
Credit card number
Private keys
API secrets
Highly confidential information

inside an ordinary JWT payload.

A Complete JWT Example

Suppose a user logs into:

https://example.com/login

They submit:

{
  "username": "noman",
  "password": "********"
}

The server verifies the credentials.

The server then creates claims:

{
  "sub": "1001",
  "name": "Noman",
  "role": "admin",
  "iat": 1720000000,
  "exp": 1720003600
}

The server signs the token.

The resulting JWT might look like:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMDAxIiwibmFtZSI6Ik5vbWFuIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzIwMDAwMDAwLCJleHAiOjE3MjAwMDM2MDB9.
SIGNATURE

The client stores the token according to the application's security architecture.

For subsequent API requests:

Authorization: Bearer <JWT>

The API validates the token before processing the request.

JWT Authentication Flow

A typical JWT authentication system works as follows:

User
  |
  | Username + Password
  v
Authentication Server
  |
  | Verify Credentials
  v
Generate JWT
  |
  v
Client
  |
  | Authorization: Bearer JWT
  v
API Server
  |
  | Verify Signature
  | Verify exp
  | Verify iss/aud where applicable
  v
Application

Let's break this down.

Step 1 — Login

The user submits credentials.

Step 2 — Authentication

The server verifies the credentials.

Step 3 — Token Generation

The server creates a JWT.

Step 4 — Token Delivery

The token is returned to the client.

Step 5 — API Request

The client sends:

Authorization: Bearer eyJ...

Step 6 — Verification

The server verifies the token.

Step 7 — Authorization

The application determines whether the user has permission to perform the requested operation.

JWT Signing Algorithms

JWT can use different cryptographic algorithms.

HS256

HS256 uses a shared secret.

Client <---- shared secret ----> Server

The same secret is used to create and verify the signature.

Advantages include simplicity and performance.

The main security concern is protecting the shared secret.

RS256

RS256 uses asymmetric cryptography.

There are two keys:

Private Key
Public Key

The issuer signs using the private key.

The recipient verifies using the public key.

Conceptually:

Private Key
     |
     v
   Sign
     |
    JWT
     |
     v
Public Key
     |
     v
  Verify

This is particularly useful when many services need to verify tokens but should not possess the signing private key.

ES256

ES256 uses elliptic-curve cryptography.

It can provide strong security with relatively small keys and signatures, although implementation and key management must be handled correctly.

JWT Encryption

A standard signed JWT does not encrypt the payload.

If confidentiality is required, the JOSE ecosystem provides JWE — JSON Web Encryption.

A simplified distinction is:

JWS:
Integrity + Authenticity

JWE:
Confidentiality + Integrity

A signed JWT answers:

Has this token been modified, and was it signed by the expected key?

An encrypted token answers:

Can someone other than the intended recipient read the information?

These are different security requirements.

In some architectures, information can be both encrypted and signed, depending on the requirements.

"Decrypting" a Normal JWT

Technically, calling it "decrypting" is incorrect for an ordinary JWT.

You normally decode it.

For example, a payload such as:

{
  "sub": "1001",
  "name": "Noman",
  "role": "admin"
}

is Base64URL encoded.

The encoded payload can be decoded without knowing the signing secret.

The important distinction is:

Decode → Can reveal payload
Verify → Confirms authenticity/integrity
Decrypt → Reveals encrypted content

These are three different operations.

Example: Creating JWT in PHP

PHP applications commonly use JWT libraries.

Conceptually, code might look like:

$payload = [
    'sub' => 1001,
    'name' => 'Noman',
    'role' => 'admin',
    'iat' => time(),
    'exp' => time() + 3600
];

$token = JWT::encode(
    $payload,
    $secretKey,
    'HS256'
);

The generated token can then be returned to the client.

Example: Verifying JWT in PHP

The API receives:

Authorization: Bearer <token>

The application extracts the token and verifies its signature.

Conceptually:

$decoded = JWT::decode(
    $token,
    new Key($secretKey, 'HS256')
);

If the token has been modified, uses the wrong signing key, or violates relevant validation requirements, verification should fail.

Example: JWT with Node.js

A Node.js application can use a JWT library to generate tokens.

Conceptually:

const token = jwt.sign(
    {
        sub: "1001",
        role: "admin"
    },
    process.env.JWT_SECRET,
    {
        expiresIn: "1h"
    }
);

Verification:

const decoded = jwt.verify(
    token,
    process.env.JWT_SECRET
);

The server should validate more than merely whether the token can be decoded.

JWT and REST APIs

JWT became especially popular with REST APIs.

For example:

POST /api/login

returns:

{
  "access_token": "eyJ..."
}

The client then calls:

GET /api/users

with:

Authorization: Bearer eyJ...

The API validates the token and processes the request.

This approach works well with:

  • Mobile applications
  • JavaScript applications
  • Backend services
  • Microservices
  • Third-party APIs
  • Distributed applications

JWT in Microservices

JWT can be particularly useful in a microservice architecture.

Imagine:

                    Authentication Service
                            |
                            | JWT
                            v
       +--------------------+--------------------+
       |                    |                    |
       v                    v                    v
   User API            Payment API          Order API

Each service can verify the token rather than requiring every request to return to the authentication service for basic token validation.

However, authorization decisions can still require centralized policy or additional service-to-service checks.

Access Tokens and Refresh Tokens

Many modern authentication systems use two types of tokens:

Access Token

Used to access APIs.

It is generally short-lived.

For example:

15 minutes
30 minutes
1 hour

Refresh Token

Used to obtain a new access token.

It generally has a longer lifetime and requires stronger protection.

Conceptually:

Login
  |
  +---- Access Token
  |
  +---- Refresh Token

Access Token expires
        |
        v
Refresh Token
        |
        v
New Access Token

Using short-lived access tokens can reduce the impact of token theft.

JWT Storage

Where the token is stored is an important security decision.

Common possibilities include:

  • Secure, HttpOnly cookies
  • In-memory application state
  • Browser storage mechanisms
  • Mobile secure storage

There is no universally correct storage mechanism for every architecture.

For browser applications, cookies with appropriate security attributes can help reduce exposure to JavaScript-based token theft, while applications must also consider CSRF protections and other browser security concerns.

Applications using browser storage must carefully consider XSS because malicious JavaScript may be able to access stored tokens.

Common JWT Security Mistakes

1. Putting Passwords in the Payload

Never do this:

{
  "username": "noman",
  "password": "mypassword"
}

JWT payloads are not automatically confidential.

2. Using Very Long-Lived Access Tokens

A token valid for months increases the potential impact if it is stolen.

Shorter access-token lifetimes can reduce exposure.

3. Not Validating Expiration

The server should validate relevant time-based claims such as exp.

4. Trusting the Payload Without Verification

Never simply decode:

JWT → Payload → Trust

Instead:

JWT
 |
 v
Verify signature
 |
 v
Validate claims
 |
 v
Authorize request

5. Weak Secrets

If HS256 is used, the signing secret needs appropriate strength and protection.

Avoid:

secret
123456
password
jwtsecret

Use a strong randomly generated secret.

6. Accepting Any Algorithm

Applications should explicitly configure which algorithms are permitted.

Do not blindly trust the algorithm indicated by an untrusted token header.

7. Ignoring Audience and Issuer

In systems where they are relevant, validate:

iss
aud

This helps ensure that a token was issued by the expected authority and intended for the expected service.

JWT Revocation

One challenge with JWT is revocation.

Suppose a token is valid for:

1 hour

but the user's account is disabled after 10 minutes.

A purely stateless validation process may still consider the token cryptographically valid until it expires.

Solutions include:

  • Short access-token lifetime
  • Refresh-token rotation
  • Token deny lists
  • Token versioning
  • Centralized session state
  • Checking account status
  • jti-based revocation mechanisms

The appropriate approach depends on the application's security requirements.

JWT vs Traditional Sessions

JWT and session-based authentication solve similar problems but use different architectures.

FeatureJWTTraditional Session
Authentication stateOften client-held tokenUsually server-side
Server storageCan be statelessUsually required
RevocationMore complicatedUsually simpler
Distributed systemsConvenientRequires shared session storage or routing
Token contentsReadable if only signedServer-side data stays server-side
ScalingCan simplify horizontal scalingOften needs shared session infrastructure
SecurityDepends heavily on implementationMature and well understood

Neither approach is automatically appropriate for every application.

JWT vs OAuth 2.0

Another common misunderstanding is treating JWT and OAuth as competing technologies.

They are different things.

JWT is a token format.

OAuth 2.0 is an authorization framework.

OAuth 2.0 can use JWT-formatted access tokens, but OAuth does not require every access token to be a JWT.

Similarly, OpenID Connect builds an identity layer on top of OAuth 2.0 and commonly uses JWTs for ID tokens.

JWT and OpenID Connect

OpenID Connect, commonly abbreviated as OIDC, uses JWT extensively.

An OIDC ID token contains claims about authentication and the authenticated user.

For example:

{
  "iss": "https://identity.example.com",
  "sub": "123456",
  "aud": "my-client",
  "exp": 1720003600,
  "iat": 1720000000
}

The application validates the token before relying on its claims.

Advantages of JWT

JWT has several important advantages.

Compact

JWTs are relatively compact and can be transmitted easily.

Portable

They can be used across programming languages and platforms.

URL Safe

JWT uses Base64URL encoding.

Distributed-System Friendly

Services can independently verify signed tokens when appropriate.

Flexible

Custom claims can carry application-specific information.

Standardized

JWT is defined by an IETF standard.

Disadvantages of JWT

JWT also has limitations.

Revocation Can Be Difficult

Once issued, a token can remain valid until expiration unless additional controls exist.

Tokens Can Become Large

Putting many claims into a token increases request size.

Payload Is Not Secret

A signed JWT can be decoded.

Key Management Matters

Security depends heavily on protecting signing keys.

Stateless Does Not Mean Automatically Secure

JWT can remove some server-side session state, but it does not eliminate authentication and authorization security requirements.

JWT in Real-World Applications

JWT can be found in many types of systems, including:

  • REST APIs
  • Mobile applications
  • Single-page applications
  • SaaS platforms
  • Microservices
  • Enterprise applications
  • Identity providers
  • API gateways
  • Distributed applications
  • Service-to-service authentication

For example, an enterprise application might issue a token containing:

{
  "sub": "50025",
  "role": "manager",
  "department": "finance",
  "scope": "invoice:read invoice:write",
  "iss": "https://identity.company.com",
  "aud": "finance-api",
  "iat": 1720000000,
  "exp": 1720003600
}

The API can then validate the token and determine whether the requested operation is authorized.

A Simple Mental Model of JWT

The easiest way to understand JWT is to remember these three concepts:

HEADER
"What algorithm and token type?"

PAYLOAD
"What claims are being carried?"

SIGNATURE
"Can I trust that these contents were not modified?"

And remember:

Encoding ≠ Encryption
Decoding ≠ Verification
Authentication ≠ Authorization
JWT ≠ OAuth

These distinctions eliminate many common JWT misunderstandings.

Recommended JWT Security Checklist

Before deploying JWT in production, consider the following checklist:

  • Use HTTPS/TLS.
  • Use strong signing keys.
  • Protect private keys and shared secrets.
  • Use short-lived access tokens where appropriate.
  • Validate exp.
  • Validate nbf where applicable.
  • Validate iss when applicable.
  • Validate aud when applicable.
  • Restrict accepted algorithms.
  • Do not put passwords in JWTs.
  • Do not put unnecessary sensitive information in payloads.
  • Protect refresh tokens carefully.
  • Consider refresh-token rotation.
  • Implement appropriate revocation mechanisms when required.
  • Protect browser applications against XSS and CSRF according to the selected token-storage architecture.
  • Log authentication events without logging sensitive tokens unnecessarily.
  • Rotate signing keys according to your operational/security requirements.
  • Use a well-maintained JWT library rather than implementing cryptographic primitives yourself.

Conclusion

JSON Web Token has become an important technology for modern authentication and authorization systems. Its standardized, compact, and portable format makes it particularly useful for APIs, mobile applications, single-page applications, microservices, and distributed architectures.

The most important thing to understand about JWT is that a normal JWT is generally signed, not encrypted. Its header and payload can be decoded by anyone who possesses the token. The signature provides integrity and authenticity when properly verified.

A JWT consists of:

Header.Payload.Signature

The header identifies the token and signing algorithm, the payload contains claims, and the signature protects the token from unauthorized modification.

JWT can significantly simplify authentication architectures, especially in distributed environments, but it is not a magic security solution. Token expiration, storage, key management, revocation, algorithm restrictions, audience validation, issuer validation, and authorization must all be considered carefully.

Understanding the difference between encoding, signing, verification, and encryption is particularly important. If confidential information needs to be protected, a normal signed JWT should not be treated as an encrypted container; appropriate encryption mechanisms such as JWE or another suitable secure channel should be considered.

Ultimately, JWT is best viewed as a standardized way of representing and securely carrying claims, rather than simply as a "login token." When implemented with proper cryptographic practices, secure transport, appropriate lifetimes, and robust validation, JWT can form an important component of a modern identity and API security architecture.

Share this article:

Continue reading more tutorials and guides

AI cyber security in 2026 and artificial intelligence threat detection Security & Cryptography

AI Cyber Security in 2026: How AI Is Changing Security

Learn how AI cyber security is changing the digital threat landscape in 2026. Discover how artificial intelligence is transforming threat detection, SOC operations, phishing defense, malware analysis, vulnerability management, cloud security, identity protection, and incident response while also creating new risks for organizations.

Muhammad Noman Muhammad Noman
15 min read