DEV Community

Asikul Islam
Asikul Islam

Posted on Originally published at blazesolutions.info

JWT Explained: How JSON Web Tokens Work

If you've worked with REST APIs, ASP.NET Core, Node.js, React, Next.js, or modern authentication systems, you've probably encountered JWT (JSON Web Token).

A JWT often looks like a long, unreadable string:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature
Enter fullscreen mode Exit fullscreen mode

But what's actually inside it, and how does JWT authentication work?

What Is JWT?

JWT stands for JSON Web Token.

It is a compact format for representing claims that can be transferred between systems. JWTs are commonly used for authentication and authorization in web applications and APIs.

A simplified authentication flow looks like this:

User
  ↓
Login
  ↓
Authentication Server
  ↓
JWT
  ↓
Client
  ↓
API Request + Bearer Token
  ↓
API Server
  ↓
Token Validation
  ↓
Protected Resource
Enter fullscreen mode Exit fullscreen mode

After a successful login, the server issues a token. The client then sends that token when accessing protected resources.

For example:

Authorization: Bearer <JWT>
Enter fullscreen mode Exit fullscreen mode

The API validates the token before trusting its claims.

The 3 Parts of a JWT

A typical signed JWT consists of three parts:

HEADER.PAYLOAD.SIGNATURE
Enter fullscreen mode Exit fullscreen mode

Each part has a different purpose.

1. Header

The header usually contains information about the token type and signing algorithm.

{
  "alg": "HS256",
  "typ": "JWT"
}
Enter fullscreen mode Exit fullscreen mode

For example, HS256 indicates HMAC using SHA-256.

2. Payload

The payload contains claims.

{
  "sub": "12345",
  "name": "John Doe",
  "role": "admin",
  "iat": 1789474800,
  "exp": 1789478400
}
Enter fullscreen mode Exit fullscreen mode

Common claims include:

  • sub — Subject
  • iss — Issuer
  • aud — Audience
  • exp — Expiration time
  • iat — Issued at
  • nbf — Not before
  • jti — JWT ID

Applications can also define custom claims.

3. Signature

The signature helps the server verify that the signed token has not been modified.

Conceptually, the signature is created from the encoded header and payload using a cryptographic algorithm and an appropriate secret or key.

This allows the server to detect tampering.

Is a JWT Encrypted?

Not necessarily.

This is one of the most important things to understand about JWT.

A normal signed JWT uses Base64URL encoding for its header and payload. Encoding does not make the information secret.

For example, if a JWT contains:

{
  "role": "admin"
}
Enter fullscreen mode Exit fullscreen mode

someone who possesses the token can generally decode that information.

Therefore, don't put passwords, secret keys, or unnecessary sensitive information inside a normal JWT payload.

Remember:

Encoding ≠ Encryption
Enter fullscreen mode Exit fullscreen mode

Decoding vs Verifying a JWT

Another common misconception is that decoding a JWT means the token is valid.

It doesn't.

Decoding allows you to inspect the contents of the header and payload.

Verification checks whether the signature is valid and whether the token meets the application's validation requirements.

For example, a decoded token might contain:

{
  "role": "admin"
}
Enter fullscreen mode Exit fullscreen mode

That doesn't prove that the server should trust the role claim.

The server must properly validate the token before using its claims for authentication or authorization.

How to Decode a JWT

A JWT can be separated into its three components using the . character:

HEADER.PAYLOAD.SIGNATURE
Enter fullscreen mode Exit fullscreen mode

The header and payload can then be Base64URL-decoded.

For example, the payload might reveal:

{
  "sub": "12345",
  "name": "John",
  "role": "user",
  "exp": 1789478400
}
Enter fullscreen mode Exit fullscreen mode

You can do this manually during development, but a JWT decoder is much more convenient when debugging APIs.

If you need to inspect a token quickly, you can use the BlazeSolutions JWT Decoder to decode and inspect the JWT header and payload.

Important: Never paste production tokens containing sensitive information into an online tool unless you understand the privacy and security implications.

How to Check JWT Expiration

One of the most useful claims when debugging authentication problems is exp.

For example:

{
  "sub": "12345",
  "exp": 1789478400
}
Enter fullscreen mode Exit fullscreen mode

The exp claim represents the token's expiration time.

If an API suddenly starts returning:

401 Unauthorized
Enter fullscreen mode Exit fullscreen mode

checking the expiration claim is a useful first step.

However, an expired token isn't the only possible reason for a 401 response. Signature validation, issuer, audience, clock differences, authentication configuration, and other factors can also cause authentication failures.

JWT Access Tokens and Refresh Tokens

Modern authentication systems often use both access tokens and refresh tokens.

An access token is typically short-lived and is used to access protected APIs.

A refresh token can be used to obtain a new access token when the existing access token expires.

A simplified flow looks like this:

Login
  ↓
Access Token + Refresh Token
  ↓
Access Token Expires
  ↓
Refresh Token
  ↓
New Access Token
Enter fullscreen mode Exit fullscreen mode

The exact implementation depends on the authentication architecture and protocol being used.

Common JWT Security Mistakes

JWT itself doesn't automatically make an authentication system secure. The implementation matters.

Some common mistakes include:

Trusting decoded claims

A decoded payload should not automatically be considered trustworthy.

Always perform proper token validation on the server.

Putting sensitive information in the payload

Avoid storing passwords, secret keys, or unnecessary confidential information in a normal JWT.

Using unnecessarily long-lived access tokens

If an access token is compromised, a long lifetime can increase the potential impact.

Skipping issuer and audience validation

If your application depends on iss and aud, make sure those claims are properly validated.

Accepting unexpected signing algorithms

Configure the server to accept only the algorithms appropriate for your authentication system rather than blindly trusting token-provided algorithm information.

JWT Debugging Checklist

When troubleshooting a JWT authentication problem, check:

  1. Token structure — Does it contain three expected sections?
  2. Header — Is the expected signing algorithm being used?
  3. Payload — Are the required claims present?
  4. Expiration — Has the token expired?
  5. Issuer — Is the token from the expected issuer?
  6. Audience — Is it intended for your API?
  7. Signature — Can the server successfully validate it?
  8. Authorization — Does the authenticated user have the required permissions?

This simple checklist can save a lot of time when debugging API authentication.

Final Thoughts

JWT is relatively simple once you understand its structure:

JWT
├── Header
├── Payload
└── Signature
Enter fullscreen mode Exit fullscreen mode

The most important distinction to remember is:

A JWT can be decoded without being verified.

Understanding that difference helps avoid many common authentication and security mistakes.

If you want a deeper explanation of JWT structure, authentication flow, claims, expiration, access and refresh tokens, security considerations, and practical debugging, read the full guide:

JWT: How It Works, Structure, Authentication, and How to Decode a JWT

For quickly inspecting a JWT during development:

BlazeSolutions JWT Decoder


What JWT-related issue have you encountered recently — expired tokens, invalid signatures, 401 Unauthorized, or something else?

Top comments (0)