BlogHow to Validate a JWT Token: Signature, Expiry & Claims
·Updated July 7, 2026·11 min read·JWTSecrets Team

How to Validate a JWT Token: Signature, Expiry & Claims

Learn how to verify JWT signatures, check expiration, and validate claims — with code examples and a free browser validator tool.

How to Validate a JWT Token: Signature, Expiry & Claims

Validating a JWT is not optional — it is the entire security model. A token that is merely decoded (base64-decoded) but not verified can be forged by anyone. This guide covers what proper validation means and how to do it.

Decode vs Verify

Decoding reads the header and payload without checking authenticity. Anyone can base64-decode a JWT and read its claims.

Verifying checks the cryptographic signature using your secret (HS256) or public key (RS256). Only verified tokens should be trusted.

// WRONG — only decodes, does not verify
const payload = jwt.decode(token);

// CORRECT — verifies signature and claims
const payload = jwt.verify(token, secret, { algorithms: ['HS256'] });

Step 1: Verify the Signature

For HS256 tokens, verification requires the same secret used to sign the token:

const jwt = require('jsonwebtoken');

try {
  const payload = jwt.verify(token, process.env.JWT_SECRET, {
    algorithms: ['HS256'], // always specify — prevents alg confusion
  });
  console.log('Valid token:', payload);
} catch (err) {
  console.error('Invalid token:', err.message);
}

Quick check: Paste your token and secret into the JWT Validator to see signature status, decoded claims, and expiration at a glance.

Step 2: Check Expiration

The exp claim is a Unix timestamp after which the token is no longer valid. Most JWT libraries check this automatically during verify().

jwt.verify(token, secret, {
  algorithms: ['HS256'],
  maxAge: '15m', // additional server-side limit
});

If a token is expired, reject it immediately — do not attempt to refresh it server-side without a valid refresh token flow.

Step 3: Validate Issuer and Audience

jwt.verify(token, secret, {
  algorithms: ['HS256'],
  issuer: 'https://auth.yourapp.com',
  audience: 'https://api.yourapp.com',
});

Without audience validation, a token issued for one service can be replayed against another.

Step 4: Inspect Claims for Authorization

After verification, use claims like sub (user ID) and role for authorization decisions. Never trust unverified claims.

Common Validation Errors

ErrorCauseFix
invalid signatureWrong secret or tampered payloadCheck secret, re-sign token
jwt expired`exp` in the pastIssue a new token
invalid algorithmalg mismatch or confusion attackSpecify `algorithms` explicitly
jwt audience invalidToken not for this serviceSet and validate `aud`

Debugging with Browser Tools

During development, use the JWT Validator to paste tokens and secrets without writing debug code. For building test tokens, use the JWT Encoder.

Express Middleware Example

Wrap validation in middleware so every protected route verifies tokens consistently:

const jwt = require('jsonwebtoken');

function authMiddleware(req, res, next) {
  const header = req.headers.authorization;
  if (!header?.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Missing token' });
  }
  const token = header.slice(7);
  try {
    req.user = jwt.verify(token, process.env.JWT_SECRET, {
      algorithms: ['HS256'],
      audience: 'https://api.yourapp.com',
      issuer: 'https://auth.yourapp.com',
    });
    next();
  } catch (err) {
    return res.status(401).json({ error: 'Invalid or expired token' });
  }
}

app.get('/api/profile', authMiddleware, (req, res) => {
  res.json({ userId: req.user.sub });
});

Never skip verification on "internal" routes — attackers probe unprotected endpoints first.

Refresh Token Pattern

Short-lived access tokens (15 minutes) limit exposure if stolen. Pair them with refresh tokens stored in httpOnly cookies:

1. Client sends access token with each API request

2. When access token expires, client calls /auth/refresh with the refresh token

3. Server issues a new access token (and optionally rotates the refresh token)

4. Server validates the refresh token against a database or Redis store (refresh tokens are typically opaque, not JWTs)

Access token validation remains stateless (signature check only). Refresh token validation requires server-side lookup — this is intentional.

Production Validation Checklist

Before shipping, confirm your API:

  • [ ] Specifies algorithms explicitly on every verify() call
  • [ ] Validates exp (most libraries do this by default)
  • [ ] Sets and checks aud and iss claims
  • [ ] Rejects tokens with unexpected alg values in the header
  • [ ] Uses HTTPS for all token transmission
  • [ ] Does not log full tokens in application logs
  • [ ] Has a secret rotation plan documented

Use the JWT Validator during QA to test edge cases: expired tokens, wrong secrets, tampered payloads, and missing claims.

Security Reminders

  • Always specify the expected algorithm in verify() options
  • Use short-lived access tokens (15–60 minutes)
  • Never log full tokens in production
  • Rotate secrets if you suspect compromise — see key rotation guide

Related Guides

Quick Debugging Tips

If validation fails in production but works locally, check these common causes:

1. Whitespace in the secret — copy-paste from env files can add trailing newlines

2. Wrong environment — staging token verified against production secret

3. Clock skew — server clocks more than 60 seconds apart can cause false exp failures

4. Algorithm mismatch — token signed with HS256 but verified with RS256 public key

Paste failing tokens into the JWT Validator with the suspected secret to isolate whether the issue is signature, expiration, or claim validation.

Written by

JWTSecrets Team

Editorial Team

The JWTSecrets editorial team writes practical guides on JWT authentication, cryptographic key management, and browser-based security tooling. Our content is reviewed against IETF RFCs and current library documentation.