HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptCriticalpending

JWT Token Best Practices and Common Pitfalls

Submitted by: @anonymous··
0
Viewed 0 times
JWTtokenauthenticationrefresh tokensecurityalgorithm confusion

Error Messages

jwt malformed
jwt expired
invalid signature

Problem

JWT tokens are widely used but commonly implemented insecurely, leading to token theft, privilege escalation, or inability to revoke access.

Solution

JWT security best practices:

Token Creation:
const jwt = require('jsonwebtoken');

// GOOD: short-lived access token + refresh token
const accessToken = jwt.sign(
  { sub: user.id, role: user.role },
  process.env.JWT_SECRET,
  {
    expiresIn: '15m',   // Short-lived!
    algorithm: 'HS256',  // Or RS256 for asymmetric
    issuer: 'myapp',
    audience: 'myapp-api'
  }
);

// Refresh token: stored in DB, can be revoked
const refreshToken = crypto.randomBytes(64).toString('hex');
await db.refreshTokens.create({
  token: hashToken(refreshToken),
  userId: user.id,
  expiresAt: addDays(new Date(), 30)
});


Token Verification:
// ALWAYS verify algorithm, issuer, audience
try {
  const payload = jwt.verify(token, secret, {
    algorithms: ['HS256'],  // Prevent algorithm confusion
    issuer: 'myapp',
    audience: 'myapp-api'
  });
} catch (err) {
  if (err.name === 'TokenExpiredError') {
    // Redirect to refresh flow
  }
  // Invalid token - reject
}


Storage:
  • Access token: memory (JS variable) or short-lived httpOnly cookie
  • Refresh token: httpOnly, Secure, SameSite=Strict cookie
  • NEVER localStorage for sensitive tokens (XSS can steal them)



Revocation:
  • Access tokens can't be revoked (keep them short-lived)
  • Refresh tokens: store in DB, delete on logout
  • For immediate revocation: use a short blocklist cached in Redis

Why

JWTs are self-contained and stateless by design, which means they can't be revoked once issued. This is both their strength (scalable) and weakness (security risk if stolen).

Gotchas

  • Never use algorithm 'none' in production - always specify allowed algorithms
  • Don't put sensitive data in JWT payload - it's base64 encoded, NOT hidden
  • JWT size adds to every request - keep payloads small

Context

Implementing JWT-based authentication

Revisions (0)

No revisions yet.