A JWT (JSON Web Token) is a compact, self-contained token that carries claims (pieces of information) about a subject, typically a user. JWTs are the dominant format for authentication tokens in REST APIs, single-page applications, and microservice architectures. They allow a service to verify who a user is without consulting a central session store.
The Three Parts of a JWT
A JWT consists of three Base64URL-encoded parts separated by dots: header.payload.signature.
The header is a JSON object that specifies the token type (JWT) and the signing algorithm (typically HS256 for HMAC-SHA256 or RS256 for RSA-SHA256).
The payload is a JSON object containing the claims. Registered claims (defined in the JWT specification) include sub (subject, typically a user ID), iat (issued at timestamp), exp (expiration timestamp), iss (issuer), and aud (audience). You can add any custom claims your application needs.
The signature is computed from the encoded header and payload using the signing algorithm and a secret key (for symmetric algorithms) or a private key (for asymmetric algorithms). The signature ensures that the token was not modified after it was issued.
How JWT Authentication Works
When a user logs in, the server verifies the credentials and issues a JWT. The server sends the JWT to the client, which stores it (typically in memory or in an HttpOnly cookie). For subsequent requests, the client includes the JWT in the Authorization header using the Bearer scheme. The server verifies the signature on each request without needing to look up a session in a database. If the signature is valid and the token has not expired, the request is authenticated.
HS256 vs RS256
HS256 uses a shared secret for both signing and verification. The same secret key that signed the token can verify it. This means any service that can verify tokens can also issue them.
RS256 uses a private key to sign and a public key to verify. Only the authentication server holds the private key and can issue tokens. Any service can have the public key and verify tokens. This is the preferred approach when tokens are verified by multiple different services.
Security Considerations
Never put sensitive data in the JWT payload. The payload is Base64URL-encoded, not encrypted. Anyone who holds the token can decode and read the payload without the secret key.
Always validate the exp claim. A token without expiration validation remains valid forever if it is stolen.
Use short expiration times for access tokens (15 minutes to 1 hour) and issue refresh tokens for longer-lived sessions.
Using the DevHexLab JWT Generator
Open the tool at /tools/security/jwt-generator. Select the algorithm, fill in the payload claims, enter the secret, and click Generate. Copy the token to use in testing, Postman, or development.
Frequently Asked Questions
Can I decode a JWT without the secret?
Yes. The header and payload are Base64URL-encoded, not encrypted. Anyone can decode them. Only the signature requires the secret to verify.
Should I use JWTs for sessions?
JWTs are stateless, which means you cannot invalidate them before they expire without maintaining a token blocklist. For sessions where you need immediate invalidation (logout, password change), stateful sessions with a server-side store may be preferable.
Understanding JWTs lets you implement authentication correctly from day one.