Skip to content
Encoding2026-07-09Begin6 min read

JWT Explained: Structure, Signature Verification, and Security Practices

What Is JWT

JSON Web Token (JWT) is an open standard (RFC 7519) for passing information securely between parties as a compact, URL-safe string. You can send it in an HTTP header, a URL parameter, or a cookie.

Two common use cases:

  • Authentication: After login, the server issues a JWT. The client carries it in later requests to prove identity. Unlike sessions, the server does not store session state, so JWT fits distributed and microservice architectures well.
  • Information exchange: JWTs carry a signature, so the receiver can verify the content has not been tampered with. This makes them useful for passing trusted data between services, such as OAuth2 access tokens.

The Three-Part Structure

A JWT looks like this, three segments separated by dots:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The three parts are Header, Payload, and Signature. Each one is Base64URL-encoded JSON.

Part 1: Header

Decoded, it describes the token type and signing algorithm:

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg: the signing algorithm. HS256 means HMAC with SHA-256.
  • typ: the token type, always JWT.

Part 2: Payload

This holds the actual data, known as claims. Decoded:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Standard claims defined by RFC 7519:

FieldMeaningDescription
issIssuerWho issued the token
subSubjectUsually the user ID
audAudienceWho the token is intended for
expExpirationToken is invalid after this time
iatIssued atWhen the token was issued
nbfNot beforeToken is not valid before this time

You can also add custom claims such as name, role, or email.

Part 3: Signature

This prevents tampering. It is covered next.

How Signature Verification Works

Take HS256, the most common algorithm. Signing works in three steps:

  1. Concatenate base64url(header) + "." + base64url(payload) into one string.
  2. Run HMAC-SHA256 over that string using a secret key.
  3. Base64URL-encode the result to get the signature.
HMACSHA256(
  base64url(header) + "." + base64url(payload),
  secret
)

When the server receives a token, it repeats the same computation and compares the result to the signature in the token. If they match, the token is authentic. Because an attacker does not know the secret, they cannot produce a valid signature for a modified payload. That is what makes the signature tamper-proof.

One detail worth knowing: Base64URL differs from standard Base64. Base64URL replaces + with - and / with _, and drops the trailing = padding. This keeps the token safe to place in a URL without special characters causing trouble.

Common Security Pitfalls

The alg: none Vulnerability

The Header contains an alg field that tells the server which algorithm to use. Some early libraries trusted this field directly. An attacker could change alg to none, drop the signature, and certain libraries would skip verification entirely.

Defense: Hardcode the list of accepted algorithms on the server (for example, only HS256). Never trust the algorithm declared inside the token.

Weak Keys

HS256 security depends entirely on the key. If it is short or predictable (like "secret" or "123456"), an attacker can brute force it and forge any token.

Recommendation: Use a random key at least 32 bytes long. Never commit it to source control.

Expiration Time

The exp claim controls how long a token stays valid. Set it too long (say, a year) and a leaked token does a lot of damage. Set it too short and users log in constantly.

A common pattern is a 15 to 30 minute access token paired with a 7 to 30 day refresh token for renewal.

Units must be Unix seconds. Issuers that write milliseconds while verifiers compare seconds cause “expired on issue” or nonsense relative times — full triage in JWT exp/nbf clock skew. Production verifiers should allow 30–60 seconds of leeway for NTP jitter.

Separate JWT failures from TLS certificate failures

TLS certificates answer “did I reach the right server?”; JWTs answer “what identity does this request claim?”. Certificate red screens belong in the certificate decoder guide / incomplete chain. HTTP 401s belong here. Reproduce them separately when both appear.

An old debate, with tradeoffs on both sides:

  • LocalStorage: Easy to implement, the frontend can read it freely. The downside is exposure to XSS attacks that steal tokens.
  • HttpOnly Cookie: JavaScript cannot read it, which blocks XSS theft. But you need the SameSite attribute to defend against CSRF.

For security-sensitive systems, prefer HttpOnly plus Secure plus SameSite=Strict cookies.

Using an Online Tool

The JWT Decoder tool from ToolVault lets you inspect and verify a JWT quickly.

Steps:

  1. Paste the JWT string into the input box.
  2. The tool decodes Header and Payload; a timeline shows exp/iat/nbf as UTC plus relative offsets.
  3. alg=none surfaces a red warning (unsigned token).
  4. HS256 can be verified locally with a secret; RS256/JWKS belongs on the server.

The tool runs entirely in your browser. Large integer claims (for example snowflake IDs) follow a lossless display path so IEEE754 rounding does not silently rewrite them.

Implementer's note

Decode and HS256 verify stay in-browser. The timeline is presentation (including a millisecond-magnitude heuristic) and does not rewrite your issuance code. Copy remains in the toolbar so claim metadata does not block the primary action. Same boundary as the certificate tools: no server-side fetch of remote material.

FAQ

What is the difference between JWT and Session?

Sessions are stateful. The server stores session data for each user. JWT is stateless. All the information lives inside the token, and the server only needs the secret key to verify it. Sessions make it easy to revoke access on demand. JWT fits distributed architectures naturally.

Can the signature be cracked?

HS256 uses HMAC-SHA256, which is cryptographically sound. The real risk is the key. If it is long and random, brute forcing is impractical. If it is something like "secret", it breaks in seconds.

It depends. Use HttpOnly cookies when you need XSS protection. Use LocalStorage when the frontend needs to read the token. Either way, always transmit over HTTPS.

Can JWT be encrypted?

Standard JWT only signs the payload. It does not encrypt it. Anyone who gets the token can decode the Base64URL and read the contents. If you need confidentiality, use JWE (JSON Web Encryption).

Article by ToolVault. Visit our homepage for more developer tools.