DEV Community

SakshamVerma 08
SakshamVerma 08

Posted on

Understanding Authentication That Actually Makes Sense

My Deep Dive into JWT Tokens: Understanding Authentication That Actually Makes Sense

While building my Fuzzie automation application, I kept running into these mysterious three-part strings that handled user authentication. After weeks of digging deep into JWTs (JSON Web Tokens), I finally understand why they're everywhere in modern web development.

Why JWTs Clicked For Me

I needed authentication for my MERN stack project, and everyone kept recommending JWTs over traditional sessions. The reason is simple: JWTs are stateless. The server doesn't need to remember anything about you. It's like having a tamper-proof ID card that proves who you are without anyone needing to check a database. This makes scaling much easier, especially when you're building APIs for both web and mobile.

The Three Parts of a JWT

A JWT looks like gibberish at first: eyJhbGci...eyJ1c2Vy...SflKxwRJ, but it's actually three pieces separated by dots.

The header tells you what type of token it is and which algorithm secures it. When decoded, it looks like this:

{
  "alg": "HS256",
  "typ": "JWT"
}
Enter fullscreen mode Exit fullscreen mode

The payload contains your actual data, like user information and permissions:

{
  "userId": "507f1f77bcf86cd799439011",
  "email": "saksham@example.com",
  "role": "user",
  "exp": 1698851832
}
Enter fullscreen mode Exit fullscreen mode

Here's something that surprised me: the payload isn't encrypted, just base64-encoded. Anyone can decode and read it. Never put passwords or sensitive data here unless you're using JWE (JSON Web Encryption).

The signature is what makes JWTs secure. It's created by hashing the header and payload together with a secret key that only your server knows. If someone tries to modify the payload, they can't recreate a valid signature without that secret key. When your server verifies the token, any tampering will be immediately detected.

How I Use JWTs in My Projects

When a user logs in, my Express backend generates a token:

const jwt = require('jsonwebtoken');

const token = jwt.sign(
  { userId, email, role },
  process.env.JWT_SECRET,
  { expiresIn: '24h' }
);
Enter fullscreen mode Exit fullscreen mode

The frontend stores this token (I use httpOnly cookies for security) and includes it in every request:

axios.get('/api/user/profile', {
  headers: { 'Authorization': `Bearer ${token}` }
});
Enter fullscreen mode Exit fullscreen mode

My backend middleware verifies each token before allowing access:

const verifyToken = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    res.status(403).json({ message: 'Invalid token' });
  }
};
Enter fullscreen mode Exit fullscreen mode

The server never needs to query a database to verify who you are. It just checks the signature mathematically.

Security Lessons I Learned

Use a strong, random secret key of at least 256 bits. Generate it once with Node's crypto module and store it in environment variables, never in your code.

Always set an expiration time. I use 24 hours for most applications, with a refresh token mechanism for longer sessions.

Don't store JWTs in localStorage because of XSS vulnerabilities. I switched to httpOnly cookies, which JavaScript can't access.

Implement token refresh logic. When the access token expires (I use 15 minutes), the client automatically requests a new one using a longer-lived refresh token. This keeps users logged in without compromising security.

For critical operations, verify data with the database rather than trusting the JWT completely. If a user's role changed after their token was issued, the token won't reflect that until it expires.

Common Mistakes I Made

I initially put email addresses in my JWTs without realizing anyone could decode and read them. While emails aren't super sensitive, it taught me to be careful about what goes in the payload.

I didn't handle token expiration gracefully at first, so users would suddenly get logged out mid-session. Adding refresh token logic fixed this.

I trusted the payload blindly instead of doing fresh database lookups for important operations. Now I know when to verify and when to trust.

What I'm Learning Next

This deep dive has given me confidence implementing JWT authentication across my projects. I'm now exploring OAuth2 integration, JWT usage in microservices, and alternatives like Paseto that address some of JWT's design limitations.

Understanding JWTs deeply rather than just copying code has made me a better developer. If you're building authentication systems, I highly recommend taking the time to really understand how they work.


About the Author: I'm Saksham Verma, a BTech CSE student passionate about full-stack development and automation. Connect with me on LinkedIn or check out my portfolio.

Tags: #JWT #Authentication #WebDevelopment #NodeJS #MERN #Security

Top comments (0)