> jwt-handler

When the user needs to generate, validate, refresh, or debug JSON Web Tokens. Use when the user mentions "JWT," "access token," "refresh token," "token rotation," "token expiration," "token validation," "bearer token," or "decode JWT." Handles secure token lifecycle including signing, verification, refresh rotation, and revocation. For full auth system design, see auth-system-setup.

fetch
$curl "https://skillshub.wtf/TerminalSkills/skills/jwt-handler?format=md"
SKILL.mdjwt-handler

JWT Handler

Overview

Implements secure JWT token lifecycle for web applications — generation, validation, refresh rotation, revocation, and debugging. Produces code that follows current security best practices including short-lived access tokens, one-time refresh rotation with family tracking, and proper key management.

Instructions

Token Generation

When creating JWT tokens:

  1. Access token: Short-lived (15 min), contains user ID and roles, signed with RS256 or ES256
  2. Refresh token: Longer-lived (7-30 days), opaque or JWT, stored hashed in database
  3. Always use asymmetric signing (RS256/ES256) for production — allows verification without the private key
  4. Minimal payload: user ID, roles, issued-at, expiration. No PII, no secrets.
// Access token payload — keep it minimal
{
  sub: "user_abc123",
  roles: ["member"],
  iat: 1708185600,
  exp: 1708186500  // 15 minutes
}

Refresh Token Rotation

Implement one-time rotation with reuse detection:

  1. Each refresh token belongs to a "family" (first token in chain)
  2. On refresh: invalidate old token, issue new access + refresh pair
  3. If a revoked token is presented → revoke ALL tokens in that family (theft detected)
  4. Store in database: token_hash, family_id, user_id, expires_at, revoked_at

Token Validation Middleware

1. Extract token from Authorization header (Bearer scheme)
2. Verify signature using public key
3. Check expiration (exp claim)
4. Check issuer and audience if configured
5. Attach decoded payload to request context
6. Return 401 with specific error: expired, invalid, missing

Key Management

  • Generate RSA 2048+ or EC P-256 key pairs
  • Store private key in environment variable or secrets manager
  • Expose public key via /.well-known/jwks.json endpoint
  • Support key rotation: include key ID (kid) in token header

Examples

Example 1: Node.js Token Service

Prompt: "Create a JWT token service with refresh rotation for my Express app"

Output:

// token.service.ts
import jwt from 'jsonwebtoken';
import crypto from 'crypto';

export class TokenService {
  generateAccessToken(user: User): string {
    return jwt.sign(
      { sub: user.id, roles: user.roles },
      process.env.JWT_PRIVATE_KEY,
      { algorithm: 'RS256', expiresIn: '15m', issuer: 'app' }
    );
  }

  async generateRefreshToken(userId: string, familyId?: string): Promise<string> {
    const token = crypto.randomBytes(32).toString('hex');
    const hash = crypto.createHash('sha256').update(token).digest('hex');
    await db.refreshTokens.create({
      tokenHash: hash,
      userId,
      familyId: familyId || crypto.randomUUID(),
      expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
    });
    return token;
  }

  async rotateRefreshToken(oldToken: string) {
    const hash = crypto.createHash('sha256').update(oldToken).digest('hex');
    const stored = await db.refreshTokens.findByHash(hash);

    if (!stored || stored.revokedAt) {
      // Reuse detected — revoke entire family
      if (stored) await db.refreshTokens.revokeFamily(stored.familyId);
      throw new TokenReuseError();
    }

    await db.refreshTokens.revoke(stored.id);
    const newRefresh = await this.generateRefreshToken(stored.userId, stored.familyId);
    const user = await db.users.findById(stored.userId);
    const newAccess = this.generateAccessToken(user);
    return { accessToken: newAccess, refreshToken: newRefresh };
  }
}

Example 2: Debug a JWT Token

Prompt: "This JWT isn't working, can you decode it? eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImV4cCI6MTcwODE4NTYwMH0.abc..."

Output:

Decoded JWT:
  Header: { alg: "RS256" }
  Payload: { sub: "user_123", exp: 1708185600 }

Issue found: Token expired at 2024-02-17T12:00:00Z (3 hours ago).
The token has no "iat" claim — consider adding it for audit logging.
No "iss" or "aud" claims — recommend adding these for multi-service setups.

Guidelines

  • Never use HS256 with a weak secret — use RS256/ES256 or HS256 with 256+ bit random key
  • Never store access tokens in localStorage — use memory variables; refresh tokens in httpOnly cookies
  • Always hash refresh tokens before database storage — SHA-256 is sufficient
  • Include "iat" claim for token age checks and audit logging
  • Set clock skew tolerance to 30 seconds for verification across services
  • Return specific 401 errors: "token_expired," "token_invalid," "token_missing" — helps client-side handling

> related_skills --same-repo

> zustand

You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.

> zoho

Integrate and automate Zoho products. Use when a user asks to work with Zoho CRM, Zoho Books, Zoho Desk, Zoho Projects, Zoho Mail, or Zoho Creator, build custom integrations via Zoho APIs, automate workflows with Deluge scripting, sync data between Zoho apps and external systems, manage leads and deals, automate invoicing, build custom Zoho Creator apps, set up webhooks, or manage Zoho organization settings. Covers Zoho CRM, Books, Desk, Projects, Creator, and cross-product integrations.

> zod

You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.

> zipkin

Deploy and configure Zipkin for distributed tracing and request flow visualization. Use when a user needs to set up trace collection, instrument Java/Spring or other services with Zipkin, analyze service dependencies, or configure storage backends for trace data.

┌ stats

installs/wk0
░░░░░░░░░░
github stars17
███░░░░░░░
first seenMar 17, 2026
└────────────

┌ repo

TerminalSkills/skills
by TerminalSkills
└────────────

┌ tags

└────────────