Base64 Encoding: When and Why to Use It
Learn what Base64 encoding is, how it works, and when to use it. Understand the difference between encoding and encryption, common use cases, and best practices for web development.
Understand JSON Web Tokens (JWT) from the ground up: how they work, their three-part structure, when to use them, security best practices, refresh token strategies, and common implementation mistakes to avoid.
I'll be honest: I used to hate JWTs. They seemed overcomplicated compared to simple session cookies. Then I built my first microservices architecture at Šikulovi s.r.o. and suddenly understood why everyone uses them. When you have five services that all need to verify a user is authenticated, sharing session state becomes a nightmare. JWTs solve that problem elegantly.
But here's the thing they don't tell you in the tutorials: JWTs are easy to implement wrong. I've seen tokens with 24-hour expiration (way too long), secrets like 'password123', and payloads containing full user profiles. This guide is everything I wish someone had told me before my first JWT security audit.
A JWT looks like gibberish: eyJhbGci...eyJzdWIi...SflKxw. But there's a structure to it. Three Base64-encoded parts separated by dots. Header tells you how it's signed, payload contains your data, signature proves nobody tampered with it.
The header is just JSON saying what type of token this is and how it's signed. After all the stuff I said about encryption - the header is just base64 encoded. Anyone can read it. The only interesting parts are the algorithm (HS256, RS256) and optionally a key ID if you're doing key rotation.
This is where your actual data lives. The spec calls these 'claims' - statements about the user. Some claims are standardized (sub, exp, iat), others you make up. Remember: this is readable by anyone. I once saw a JWT with the user's SSN in it. Don't be that developer.
The signature is what makes JWTs secure. It's created by signing the header and payload with a secret (HMAC) or private key (RSA). If anyone modifies the payload, the signature won't match. If they don't have the secret, they can't create a valid signature.
This is the flow I implement for most projects. Simple, standard, works everywhere. The key insight is that after login, the server never needs to look up the token in a database - it just verifies the signature and reads the claims.
JWTs are not always the answer. I see people using them for simple login forms where session cookies would be simpler. Here's when I actually reach for JWTs:
Yep, sometimes I recommend against JWTs. For a simple server-rendered app with one database, session cookies are simpler and arguably more secure. JWTs add complexity, and complexity breeds bugs.
Modern JWT implementations use two types of tokens: short-lived access tokens for API requests and long-lived refresh tokens to obtain new access tokens. This pattern balances security with user experience.
The refresh token flow extends user sessions without requiring re-authentication while maintaining security through short-lived access tokens.
Where you store JWTs significantly impacts your application's security. Each storage option has trade-offs between security and convenience.
One of the most critical JWT vulnerabilities is the "none" algorithm attack. Some JWT libraries accept tokens with "alg": "none", which means no signature verification.
Algorithm confusion occurs when an attacker tricks the server into using a different algorithm than intended, particularly switching between symmetric (HMAC) and asymmetric (RSA) algorithms.
Proper token lifecycle management is essential for JWT security. Tokens that never expire or live too long create significant security risks.
JWTs are stateless by design—the server does not track issued tokens. This creates a challenge when you need to invalidate tokens (user logout, password change, security breach).
JWT implementations often contain security vulnerabilities due to misunderstanding how tokens work. Avoid these common mistakes.
JWTs can be signed with symmetric algorithms (HMAC) or asymmetric algorithms (RSA, ECDSA). The choice depends on your architecture and security requirements.
Following these best practices will help you implement JWTs securely. Security requires attention to detail—one mistake can compromise your entire authentication system.
Use established, well-maintained libraries for JWT handling. Never implement JWT signing or verification yourself—the cryptographic details are easy to get wrong.
When troubleshooting JWT issues, you need to inspect the token contents. Remember that anyone can decode a JWT—only the signature provides security.
JWTs provide a powerful mechanism for stateless authentication in modern web applications. Their self-contained nature makes them ideal for microservices, APIs, and single sign-on scenarios. However, JWTs require careful implementation to be secure.
Remember: JWTs are encoded, not encrypted—anyone can read the payload. Security comes from the signature verification and proper claim validation. Use short-lived access tokens with refresh token rotation, store tokens securely, and always verify signatures with explicit algorithm whitelists. Use our JWT Decoder tool to understand token structure and debug authentication issues.
JWT stands for JSON Web Token. It is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. JWTs are commonly used for authentication and information exchange in web applications.
No, the JWT payload is encoded (Base64URL), not encrypted. Anyone with access to the token can decode and read the payload contents. Never store sensitive information like passwords or credit card numbers in JWT payloads. If you need encrypted tokens, use JWE (JSON Web Encryption).
Access tokens should have short lifetimes, typically 5-15 minutes. This limits the damage if a token is stolen—the attacker has a small window to use it. Use refresh tokens (with longer lifetimes) to issue new access tokens without requiring users to log in again.
Access tokens are short-lived tokens (minutes) sent with every API request to authenticate the user. Refresh tokens are longer-lived tokens (days to weeks) stored securely and used only to obtain new access tokens when the current one expires. This separation improves security by limiting exposure of the frequently-used access token.
JWTs are stateless by design and cannot be directly revoked. To invalidate tokens, you need additional infrastructure: a token blacklist (stored in Redis or a database), short expiration times to minimize the revocation window, or refresh token revocation to prevent new access tokens. Each approach adds some state to your otherwise stateless system.
For web applications, HttpOnly cookies with SameSite=Strict are generally more secure because JavaScript cannot access them, protecting against XSS attacks. localStorage is vulnerable to XSS but easier to implement for APIs. For SPAs, consider storing tokens in memory only with silent refresh mechanisms. Never store tokens in URLs.
The "none" algorithm attack exploits JWT libraries that accept tokens with {"alg": "none"}, which means no signature. Attackers can forge tokens without knowing the secret. Always configure your JWT library to reject the "none" algorithm and explicitly whitelist only the algorithms you expect (e.g., ["HS256"] or ["RS256"]).
Use HS256 (HMAC) when a single service both issues and verifies tokens—it is simpler and faster. Use RS256 (RSA) when multiple services need to verify tokens but only one service should issue them—verifiers only need the public key, keeping the private signing key secure. RS256 is common in OAuth/OpenID Connect scenarios.
Founder of CodeUtil. Web developer building tools I actually use. When I'm not coding, I experiment with productivity techniques (with mixed success).
Learn what Base64 encoding is, how it works, and when to use it. Understand the difference between encoding and encryption, common use cases, and best practices for web development.
Learn the critical differences between escaping and parameterized queries for SQL injection prevention. Understand why parameterization is the gold standard for database security.
Learn how JWT claims work, explore registered, public, and private claims, and discover security best practices for implementing JSON Web Tokens in your applications.