
Online JWT Encoder: Create and Sign Tokens Without Installing Anything
📷 Pixabay / PexelsOnline JWT Encoder: Create and Sign Tokens Without Installing Anything
Learn how to create signed JWTs in your browser for testing, debugging, and mocking auth flows — without pasting your real secret into someone else's server.
Every developer learns what a JWT is at roughly the same moment: the first time they have to implement authentication and someone suggests it. You read the RFC, look at the base64-decoded payload, think "huh, that's just JSON" — and then spend the next hour confused about what exactly the signing part is doing and why.
The confusion is understandable. JWTs are simple in structure but subtle in security implications. This guide focuses on the practical side: what you actually need to know to create and use JWTs for testing and debugging, and how the JWT Encoder at ToolBox Hubs lets you do that without installing a library or spinning up a server.
What a JWT Actually Is
A JSON Web Token is three base64url-encoded strings joined by dots: header.payload.signature.
The header identifies the token type and the signing algorithm:
{
"alg": "HS256",
"typ": "JWT"
}
The payload contains claims — basically key-value pairs of information:
{
"sub": "user_12345",
"email": "alice@example.com",
"role": "admin",
"iat": 1714000000,
"exp": 1714086400
}
The signature is a cryptographic hash of the encoded header and payload, created using your secret key. It's what makes the token tamper-evident — change a single character in the payload, and the signature no longer matches.
Here's the thing that trips a lot of people up: the payload is not encrypted. It's base64url-encoded, which means anyone who holds the token can decode and read it immediately. The signature proves the token wasn't tampered with, but it does nothing to hide the contents. This matters a lot for what you decide to put in there.
The Claims You Actually Use
The JWT spec defines a handful of "registered claims" — field names with standard meanings that libraries know how to validate automatically.
sub (subject) — Who the token is about. Usually a user ID or account identifier. Should be stable and unique. A common mistake: putting an email address here instead of an opaque ID. Email addresses change; opaque IDs don't.
iat (issued at) — Unix timestamp of when the token was created. Useful for debugging, and some validation logic checks this to reject tokens that appear to be from the far future (clock skew attacks).
exp (expiration) — Unix timestamp after which the token should be rejected. This is important. A JWT without an expiration is valid forever, which means if it leaks, you have no recourse short of rotating the secret entirely. For short-lived sessions, 15-60 minutes is common. For refresh tokens, hours to days. Always set this.
iss (issuer) — A string identifying who issued the token. Useful in multi-service environments to make sure you're validating tokens from the right source. Your validation middleware can check that iss matches an expected value and reject anything else.
aud (audience) — Who the token is intended for. Prevents a token issued for Service A from being used against Service B. Often an API identifier or a list of services that should accept the token.
Custom claims are fine and common. If your app needs to embed a role, plan, org_id, or any other context into the token to avoid database lookups on every request, add those too. Just remember: anyone can read them.
When You'd Actually Use an Online JWT Encoder
The honest answer is: not for production. For production, your auth server handles signing — your secret never leaves the server environment, and tokens are generated programmatically as part of a login flow.
Where an online encoder is genuinely useful:
Testing auth middleware without a running auth server. You're building the backend endpoint that validates JWTs, and you want to test it manually. You need a valid token signed with a known secret to paste into Postman or curl. An online encoder gives you that in seconds.
Mocking auth in local development. Your frontend is building against an API that requires authentication, but the auth service isn't set up locally yet. Generate a token with the right claims and a test secret, hardcode it in your dev environment, move on. You're not shipping this; you're unblocking local development.
Debugging token validation failures. A token is being rejected by your server and you're not sure why. Is exp in the past? Is iss wrong? Is the payload malformed? An encoder lets you create a known-good token to compare against, and a JWT decoder lets you inspect the bad one. Together they're a debugging loop.
Understanding JWT behavior for the first time. The best way to understand what a library does with a JWT is to create one yourself and watch what happens. Tweak the expiration, change the algorithm, observe what breaks. An online tool makes this hands-on without the friction of code.
How HS256 Signing Works (Without the Math)
HS256 stands for HMAC-SHA256. HMAC is a construction that uses a hash function (SHA-256 in this case) together with a secret key to produce a message authentication code.
The process in plain terms: take the encoded header, add a dot, add the encoded payload. Feed that string and your secret key into the HMAC-SHA256 function. You get back a fixed-length hash. Base64url-encode that hash and append it as the third part of the token.
Why does this work? Because HMAC is designed so that without knowing the secret key, you can't produce a valid hash for a given message. If someone modifies the payload, they can't recalculate the signature to match — they'd need the secret to do that. When your server validates a JWT, it re-runs the same HMAC-SHA256 computation on the header and payload it received, compares the result to the signature in the token, and accepts or rejects accordingly.
The ToolBox Hubs encoder does this computation using the browser's built-in Web Crypto API — the same cryptographic primitives used by browsers for TLS. It's not doing this in hand-rolled JavaScript or a sketchy third-party library. That's worth knowing.
What HS256 Can't Do
HS256 uses a symmetric key — the same secret that signs the token also verifies it. This means anyone who can verify your tokens can also create them. In a system where one server issues tokens and another verifies them, both servers need to know the secret. Sharing secrets between services is a coordination and security surface problem.
RS256 (and ES256) use asymmetric keys. A private key signs tokens — only the auth server needs this, and it never leaves that server. A public key verifies tokens — this can be distributed freely, published in a JWKS endpoint, loaded by any service that needs to verify tokens. Services can verify without having any ability to mint.
For anything more complex than a single backend service, RS256 is usually the better architectural choice. HS256 is simpler to set up and fine for smaller systems or scenarios where you control all the validators.
The Security Stuff Worth Repeating
Don't put sensitive data in JWTs. Password hashes, credit card numbers, PII that doesn't need to be there — none of it. The payload is visible to anyone who holds the token. That includes the client, any logging system that captures auth headers, and any proxy or CDN in between. Treat the JWT payload like you'd treat a URL query string: assume it's visible.
Use test secrets with online tools. Even when a tool is genuinely client-side and not sending your data anywhere, the habit of typing production secrets into browser UIs is a bad one. Create a test secret. Use test-secret-do-not-use-in-production as your key if you want. Treat the real secret like a password: it doesn't leave the server it lives on.
Always set an expiration. A JWT without exp is a forever credential. If it leaks, you have a problem until you rotate the signing key — which invalidates all existing tokens and logs everyone out. Short-lived tokens plus a refresh token flow is the standard pattern for a reason.
Algorithm confusion attacks are real. Some JWT libraries had historical vulnerabilities where you could change the alg header to none and the library would accept unsigned tokens. Always validate the algorithm your server expects and reject anything else. Don't trust the alg header from the token itself.
ToolBox Hubs vs. jwt.io
jwt.io is the canonical JWT tool and most developers know it. It's good. But there are two reasons you might prefer ToolBox Hubs:
First, ToolBox Hubs is explicitly privacy-first and client-side only. jwt.io has historically received scrutiny about whether secrets typed into it might be logged. I'm not saying jwt.io is malicious — but when the privacy model of a tool isn't clearly documented, the risk calculus changes. Our tool processes everything in your browser.
Second, ToolBox Hubs integrates with related tools. After encoding a JWT, you can jump directly to the JWT Decoder to inspect it, run the payload through the Hash Generator if you need to hash any values, or use Text Encrypt/Decrypt if you need symmetric encryption for something the JWT payload shouldn't carry in plaintext.
That said: jwt.io has features we don't, including library selection and RS256 support with key pair generation. Use the right tool for what you need.
A Practical Workflow for Local Dev
Here's how I actually use a JWT encoder during development:
-
Decide what claims the token needs — usually
sub,exp, and whatever app-specific claims your middleware checks (likeroleororg_id). -
Set
expto something far enough in the future that it won't expire during a debugging session. I usually do current Unix time plus 86400 (24 hours). The Timestamp Converter helps with the mental math. -
Type in a memorable test secret — something obviously fake like
dev-secret-not-real. -
Generate the token and paste it into your API client (Postman, curl, HTTPie, whatever).
-
When something goes wrong with validation, paste the token into the JWT Decoder to confirm the payload looks right, then check your server's expected secret and algorithm match what you used to generate it.
This loop resolves 90% of JWT-related debugging confusion. The remaining 10% is usually clock skew (your exp is off) or algorithm mismatch (you generated HS256, your library expects RS256).
What the Tool Won't Do
Being honest about limitations:
No RS256 or ES256 support. Asymmetric key signing isn't available — you'd need to provide a private key, and handling that in a browser UI adds complexity. For RS256 testing, the local jsonwebtoken npm package or the python-jose library are more appropriate.
No token revocation. JWTs are stateless by design — once issued, they're valid until expiration (assuming the signature validates). There's no built-in revocation. If you need the ability to invalidate specific tokens before they expire, you need a token blocklist on your server. The encoder can't help with that; it's an architectural concern.
No JWKS generation. For RS256-based systems, you'd also want a JWKS (JSON Web Key Set) endpoint. That's out of scope for this tool.
For everything that's in scope — creating HS256-signed tokens for testing and debugging, understanding JWT structure, mocking auth in local dev — the JWT Encoder gets the job done without ceremony.
Getting Started
Open the JWT Encoder tool, type a simple payload like {"sub": "test-user", "role": "admin"}, set a test secret, and hit Generate. Look at the output. Then paste it into the JWT Decoder and watch it come apart.
Once you've done that once, JWT structure stops being abstract. You know what the three parts are, you know what base64url-encoded JSON looks like, and you know that the signature is just a hash. Everything else — library integration, algorithm selection, claims validation — builds on that foundation.
Related tools worth having open alongside this one: JWT Decoder for inspecting tokens, Hash Generator for understanding what HMAC produces, and Text Encrypt/Decrypt for the cases where base64-encoded plaintext really isn't good enough.