Tool

JWT Encoder

Construct and sign JSON Web Tokens with custom headers and payloads. Signing uses HS256 via the Web Crypto API — client-side only.

Signed with HS256 using the Web Crypto API. Client-side only.

How to Use This Tool

Edit the header JSON to set your algorithm (HS256 is selected by default) and token type. The header is automatically base64url-encoded when the token is generated.

Edit the payload JSON to include your claims. Standard claims include "sub" (subject), "exp" (expiration as a Unix timestamp), "iat" (issued at), and "aud" (audience). Add any custom claims your application needs.

Enter your HS256 secret key and click "Encode" to generate a signed JWT. Copy the resulting token to use in your application or to test with the JWT Validator tool.

Code Examples

const jwt = require('jsonwebtoken');

const payload = {
  sub: 'user_123',
  name: 'Jane Doe',
  role: 'admin',
  iat: Math.floor(Date.now() / 1000),
  exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour
};

const secret = 'YOUR_SECRET_HERE';

const token = jwt.sign(payload, secret, { algorithm: 'HS256' });
console.log(token);

Frequently Asked Questions

What claims should I include in my JWT payload?

Always include "exp" (expiration) to limit token lifetime — a token without "exp" never expires, which is a security risk. Include "sub" (subject, typically a user ID), "iat" (issued at), and "aud" (audience) for complete validation. Add only the claims your application needs — avoid embedding sensitive data like passwords or financial information in the payload.

Why is my generated token different each time even with the same payload?

If your payload includes time-based claims like "iat" (issued at), the token will change each time you encode because the timestamp changes. If you use a static payload with no time-based claims, the token will be identical each time for the same secret.

How do I set a token expiration?

Set the "exp" claim to a Unix timestamp (seconds since epoch). For example, to expire in 1 hour: Math.floor(Date.now() / 1000) + 3600 in JavaScript, or int(time.time()) + 3600 in Python. Keep access token lifetimes short (15-60 minutes) and use refresh tokens for longer sessions.

Can I use this encoder for production token signing?

This tool is intended for development, debugging, and learning. For production, sign tokens in your backend application code where the secret is stored securely in environment variables — never sign tokens in client-side JavaScript where the secret could be exposed.

Related Tools