Complete Guide to JWT Generator: Create Secure JSON Web Tokens
Learn how to generate, sign, and debug JSON Web Tokens (JWT). Master JWT structure, algorithms, claims, security best practices, and authentication patterns.
Table of Contents
Complete Guide to JWT Generator: Create Secure JSON Web Tokens
If you've built a modern web application in the last decade, you've almost certainly crossed paths with JSON Web Tokens (JWT). They're the backbone of stateless authentication, the workhorse of OAuth flows, and the quiet little string that lets your frontend prove to your backend who the user is β without a single database lookup on every request.
But here's the catch: generating a valid, correctly signed JWT by hand is tedious. You need to base64url-encode a header, base64url-encode a payload, concatenate them with a dot, run them through HMAC-SHA256 (or RSA, or ECDSA), base64url-encode the signature, and hope you didn't flip a single byte along the way. One mistake and your token is rejected with a cryptic invalid signature error.
That's exactly why a JWT Generator is one of the most useful tools in a developer's belt. Whether you're prototyping an auth flow, debugging a failing login request in Postman, writing integration tests that need valid tokens, or simply trying to understand what's actually inside that long string your backend hands out, a good generator saves you time and headaches.
In this guide, we'll walk through everything you need to know about JWTs and how to get the most out of a JWT generator β from the underlying structure of a token, to choosing the right signing algorithm, to the security pitfalls you absolutely must avoid in production.
What is a JWT?
A JSON Web Token (pronounced "jot") is a compact, URL-safe way to represent claims β pieces of information you want to transmit between two parties β as a JSON object. Defined in RFC 7519, JWTs are most commonly used for authentication and secure information exchange.
A JWT is always made up of three parts, separated by dots:
xxxxx.yyyyy.zzzzz
Concretely:
- Header β metadata about the token, including the type and signing algorithm.
- Payload β the actual claims (data) you're transmitting.
- Signature β a cryptographic proof that the token hasn't been tampered with.
Here's what a real JWT looks like:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Decoding the three parts
1. Header β The header typically consists of two fields: alg (the signing algorithm) and typ (the token type, almost always JWT). This JSON object is base64url-encoded to form the first part of the token.
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload β The payload contains the claims: statements about an entity (typically the user) and additional metadata. There's a set of standard "registered" claims (iss, sub, exp, etc.) and you can add any custom claims you like. This JSON object is also base64url-encoded.
{
"sub": "1234567890",
"name": "Jane Doe",
"iat": 1516239022
}
3. Signature β To create the signature, you take the encoded header, the encoded payload, a secret (or private key), and sign them using the algorithm specified in the header. For HMAC-SHA256:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret )
The resulting signature is the third part of the token. When your backend receives the token, it recomputes the signature using the same secret and compares it to the one in the token. If they match, the token is authentic and hasn't been modified.
Base64url encoding
JWTs use base64url encoding β a variant of base64 that's safe to put in URLs. It replaces + with -, / with _, and drops the = padding. This matters: you can't just atob() a JWT segment in JavaScript and expect it to always work cleanly, because standard base64 decoding will choke on the - and _ characters. (A JWT generator handles this for you automatically.)
Important: base64url encoding is not encryption. The header and payload of a JWT can be decoded and read by anyone who has the token. Only the signature is cryptographically protected. Never put a password, credit card number, or any secret data in a JWT payload.
Why Use a JWT Generator?
You could absolutely generate a JWT by hand using a script, OpenSSL, or the jsonwebtoken package in Node.js. So why reach for a dedicated generator tool instead?
- β‘ Rapid prototyping β Spin up a token in seconds while building a new API or testing a login flow. No need to write a throwaway script every time.
- π Easier debugging β When a request fails with 401 Unauthorized, you need to inspect the token fast. A generator that also decodes and previews the result lets you see exactly what's being produced.
- π§ͺ Testing auth flows β Generating tokens with specific claims, custom expiry windows, or deliberately expired timestamps is essential for writing good integration and end-to-end tests.
- π Learning by doing β If you're new to JWTs, there's no better way to understand the structure than to tweak a payload, regenerate, and watch the signature change in real time.
- π No backend required β A client-side generator runs entirely in your browser. Your secrets never leave your machine, which is both faster and more private than pasting your token into an online service you don't trust.
- π Algorithm switching β Need to compare an HS256 token with an RS256 one? A generator lets you flip algorithms and see the result instantly without reconfiguring a library.
- π Copy-paste ready β Generate, click, and paste directly into Postman, your .env file, a test fixture, or a cURL command.
In short, a JWT generator is one of those small tools that quietly pays for itself every single day you work with authentication.
Key Features
Our JWT Generator is built to cover the full spectrum of token-generation needs, from quick one-offs to structured test fixtures. Here's what you get:
| Feature | Description |
|---|---|
| HMAC algorithms | Sign tokens with HS256, HS384, and HS512 using a shared secret key. The fastest, simplest option for monolithic apps and internal services. |
| RSA algorithms | Sign tokens with RS256, RS384, and RS512 using a public/private key pair. Ideal for distributed systems where the verifier can't be trusted with the signing key. |
| Standard claims support | Built-in fields for iss (issuer), sub (subject), aud (audience), exp (expiry), and iat (issued-at) with friendly date/time pickers. |
| Custom claims | Add any private claims you need by editing the payload JSON directly β roles, permissions, tenant IDs, you name it. |
| Real-time preview | The generated token updates instantly as you type, with a live decode panel showing the parsed header and payload so you can verify your input. |
| Secret key input | Paste any secret string for HMAC, or a PEM-formatted private key for RSA. The input is masked and never sent anywhere. |
| Expiry configuration | Pick a preset (1 hour, 1 day, 7 days, 30 days) or enter a custom Unix timestamp for precise control over token lifetime. |
| Copy to clipboard | One-click copy of the final token, ready to paste into your API client, config file, or test harness. |
| 100% client-side | Everything runs in your browser. No tokens, secrets, or keys are transmitted to a server, ever. |
| Algorithm comparison | Quickly switch between algorithms and key types to see how the token structure and length change. |
How to Use the JWT Generator
Generating a JWT with our tool takes about 30 seconds. Here's the full walkthrough.
Step 1: Open the JWT Generator
Head over to the JWT Generator page. You'll be greeted with a clean form split into three sections: algorithm selection, header & payload editing, and secret/expiry configuration. The generated token appears in a preview box at the bottom.
Step 2: Choose Your Signing Algorithm
Pick the algorithm that matches your backend's expectations. The most common choices are:
- HS256 β HMAC with SHA-256. Uses a single shared secret. Great for most apps.
- RS256 β RSA signature with SHA-256. Uses an asymmetric key pair. Great for microservices and third-party verifiers.
If you're not sure, HS256 is the safe default for a typical web app where the same service signs and verifies tokens.
Step 3: Fill In the Header
The header is mostly auto-filled based on your algorithm choice. The standard header looks like:
{
"alg": "HS256",
"typ": "JWT"
}
You usually don't need to change anything here unless you're adding a kid (key ID) header for key rotation, or a custom header parameter. The alg field is set automatically when you choose an algorithm.
Step 4: Add Your Claims (Payload)
This is where you define what the token actually says. Start with the standard claims, then layer on anything custom. Here's a realistic example payload for an authenticated user:
{
"iss": "https://auth.myapp.com",
"sub": "usr_8f23a1c9",
"aud": "myapp-api",
"iat": 1782105600,
"exp": 1782192000,
"name": "Jane Doe",
"email": "[email protected]",
"role": "admin",
"tenant": "acme-corp"
}
- iss, sub, aud, iat, exp are standard registered claims (covered in detail below).
- name, email, role, tenant are custom claims specific to your application.
π‘ Tip: The live preview panel decodes your payload as you type, so you'll immediately spot any JSON syntax errors before copying the token.
Step 5: Set Your Secret and Expiry, Then Copy
Enter your secret key (for HMAC) or paste your RSA private key (for RSA). Set the expiry β either pick a preset or enter a specific timestamp. The generated token appears in the preview box and updates in real time.
Once you're happy with it, hit Copy and paste the token wherever you need it:
# Use it in a cURL request
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfOGYyM2ExYzkiLCJyb2xlIjoiYWRtaW4ifQ.signature-here" \
https://api.myapp.com/profile
// Or use it in JavaScript
const response = await fetch('/api/profile', {
headers: {
Authorization: `Bearer ${token}`,
},
});
That's it. You've generated a signed, valid JWT in seconds.
Understanding JWT Claims
Claims are the heart of a JWT β they're the statements about the user, the issuer, and the token itself. JWT defines three types of claims: registered (standardized), public (defined in the IANA registry), and private (custom to your application).
Registered (standard) claims
These are the reserved, three-letter claim names defined by the JWT spec. Use them when they apply β your libraries and verifiers understand them out of the box.
| Claim | Full Name | Description | Example |
|---|---|---|---|
| iss | Issuer | The principal that issued the token. Usually a URL identifying your auth service. | "iss": "https://auth.myapp.com" |
| sub | Subject | The principal the token is about β typically the user ID. Must be unique within the issuer. | "sub": "usr_8f23a1c9" |
| aud | Audience | The intended recipient(s) of the token. Your API should reject tokens not meant for it. | "aud": "myapp-api" |
| exp | Expiration Time | Unix timestamp after which the token must not be accepted. Always set this. | "exp": 1782192000 |
| nbf | Not Before | Unix timestamp before which the token must not be accepted. Useful for delayed activation. | "nbf": 1782105600 |
| iat | Issued At | Unix timestamp when the token was issued. Useful for detecting stale tokens. | "iat": 1782105600 |
| jti | JWT ID | A unique identifier for the token. Used to prevent replay attacks (token revocation lists). | "jti": "a3f2b8c1-..." |
Private (custom) claims
Beyond the standard ones, you can add any claims you want. These are called private claims, and they're how you actually carry your application's data:
{
"name": "Jane Doe",
"email": "[email protected]",
"role": "admin",
"permissions": ["read:users", "write:settings"],
"tenant": "acme-corp",
"plan": "enterprise"
}
β οΈ Best practice: Avoid short, generic private claim names like sub-style collisions. The spec recommends prefixing custom claims to avoid future conflicts with registered claims β for example, myapp_role instead of just role in high-interoperability scenarios.
Keep payloads small
Remember that the entire payload is base64-encoded and sent on every authenticated request. A bloated payload with megabytes of user profile data will slow down every API call and inflate your bandwidth bill. Keep JWTs lean β put only what you need for auth decisions in the token, and fetch the rest from your database when needed.
Signing Algorithms Explained
Choosing the right signing algorithm is one of the most important security decisions you'll make. JWT supports a whole family of algorithms, but in practice two dominate: HMAC (the HS* family) and RSA (the RS* family).
HMAC (HS256, HS384, HS512)
HMAC-based JWTs use a shared secret for both signing and verification. The same key that creates the signature is also used to verify it.
HMACSHA256(encodedHeader.encodedPayload, secret) β signature
- β Simple β one key to manage.
- β Fast β HMAC is computationally cheap.
- β Small signatures β keeps tokens compact.
- β Symmetric β anyone who can verify can also forge tokens.
- β Key distribution problem β every service that verifies tokens needs the secret, which increases the attack surface.
Use HMAC when: The same party (or a tightly trusted set of services) signs and verifies tokens β e.g., a monolithic app, or internal microservices behind the same trust boundary.
RSA (RS256, RS384, RS512)
RSA-based JWTs use an asymmetric key pair: a private key signs the token, and a public key verifies it.
RSASign(encodedHeader.encodedPayload, privateKey) β signature RSAVerify(encodedHeader.encodedPayload, signature, publicKey) β true/false
- β Asymmetric β verifiers can't forge tokens.
- β Safe key distribution β public keys can be freely shared (e.g., via a JWKS endpoint).
- β Ideal for third-party verifiers β any service can verify your tokens without ever seeing your signing key.
- β Larger signatures β RSA signatures are longer, so tokens are bigger.
- β Slower β RSA signing/verification is computationally heavier than HMAC.
- β More key management β you need to generate, store, and rotate key pairs.
Use RSA when: Tokens are issued by a central authority and verified by many independent services β e.g., OAuth/OIDC providers, microservice architectures, SSO systems, or anything where the verifier shouldn't be trusted with the signing key.
Comparison at a glance
| HMAC (HS256) | RSA (RS256) | |
|---|---|---|
| Key type | Shared secret (symmetric) | Public/private key pair (asymmetric) |
| Signature size | Small (~43 chars) | Large (~344 chars) |
| Performance | Very fast | Slower |
| Who can verify? | Anyone with the secret | Anyone with the public key |
| Who can forge? | Anyone with the secret | Only the private-key holder |
| Key distribution | Secret must be shared securely | Public key can be published freely |
| Best for | Monolithic apps, trusted internal services | OAuth providers, microservices, SSO, third-party verifiers |
π Security warning: Never use the alg: "none" algorithm in production. It produces unsigned tokens that any attacker can forge. Always explicitly whitelist the algorithms your verifier accepts β never trust the alg header blindly.
Common Use Cases
A JWT generator isn't just a toy β it slots into real workflows across the development lifecycle. Here's where it shines:
- π API authentication β Generate tokens to test your protected API endpoints without standing up a full login flow. Perfect for manual testing in Postman or Insomnia.
- π Single Sign-On (SSO) and OAuth β Simulate the tokens an identity provider would issue, so you can test your OAuth client and resource server locally.
- π°οΈ Microservices authentication β Generate tokens signed with different keys to verify that each service correctly validates signatures and enforces audience claims.
- π Testing and debugging expired tokens β Create tokens with past exp timestamps to confirm your backend correctly rejects them, or with future nbf to test not-yet-valid handling.
- π€ CI/CD test fixtures β Bake valid and invalid tokens into your test suite. Generate a fresh set before each run, or commit long-lived test tokens for deterministic assertions.
- π Learning and onboarding β New team members can experiment with claim structures and algorithm choices to build intuition for how JWT auth actually works.
- π§© Frontend development β Generate realistic tokens to mock your auth layer while the backend is still being built, so you can wire up Authorization headers right away.
Security Best Practices
JWTs are powerful, but they're easy to misuse. Follow these rules to keep your auth flow secure:
- π« Never hardcode secrets in frontend code. Anything shipped to the browser is publicly readable. Signing keys belong on the server, full stop.
- β±οΈ Use short token expiries. Access tokens should expire in minutes, not months. Pair them with refresh tokens for long sessions. A stolen short-lived token is far less damaging than a stolen permanent one.
- β Always validate the signature server-side. Never trust a token's payload just because it parses. Verify the signature against your known secret or public key, and check the alg explicitly.
- πͺ Prefer httpOnly, Secure, SameSite cookies for storage. Storing tokens in localStorage or sessionStorage exposes them to XSS attacks. Cookies with the httpOnly flag can't be read by JavaScript at all.
- π Always use HTTPS. Tokens in transit without TLS can be intercepted and replayed. There is no excuse for plain HTTP on an authenticated endpoint.
- π Rotate your signing keys regularly. Don't use the same secret forever. Rotate keys, support overlapping kid values during the transition, and have a revocation strategy.
- πͺ Implement token revocation. JWTs are stateless by design, which means you can't easily revoke one before it expires. Use short expiries plus a blacklist (keyed on jti) for critical cases like forced logouts.
- π― Enforce audience (aud) and issuer (iss) claims. A token minted for one service shouldn't be accepted by another. Verify these claims explicitly on every request.
- π« Avoid alg: "none". Whitelist only the algorithms you actually use when verifying, and reject unsigned tokens outright.
- π¦ Keep payloads minimal. Don't stuff sensitive data or large blobs into the token. If the data is sensitive, store it server-side and reference it by ID in the token.
Security is a moving target, but these fundamentals will keep the vast majority of attacks at bay.
Start Generating JWTs Today
Ready to put this into practice? Our JWT Generator runs entirely in your browser, supports both HMAC and RSA algorithms, and gives you a live preview of your token as you build it. Whether you're shipping a new API, debugging a flaky auth flow, or just learning how JWTs work, it's the fastest way to get a valid, signed token into your hands.
Give it a try and see how much smoother your authentication workflow can be.
Related Tools You Might Like:
- JWT Decoder β Paste any JWT and instantly inspect its header, payload, and expiry.
- HMAC Generator β Generate HMAC signatures for arbitrary messages using SHA-256, SHA-384, and SHA-512.
- Base64 Tool β Encode and decode Base64 and Base64URL strings, the encoding format used by every JWT.
Happy token generating!