Skip to main content

Authentication Best Practices

In the world of security, we assume that attackers are smart and persistent. Following these rules will protect your application from 99% of common attacks.

1. Password Security

Use Salted Hashing

As we learned, never store passwords as plain text. Use Bcrypt with at least 10-12 salt rounds.

Enforce Strong Password Policies

Don't let users use password123. Require a mix of:

  • Minimum 8-12 characters.
  • At least one uppercase letter.
  • At least one number and one special character.

2. Transport & Storage

HTTPS is Non-Negotiable

Without SSL/TLS (HTTPS), passwords and JWTs are sent across the internet in plain text. Any "man-in-the-middle" can steal them. Always use HTTPS in production.

Use HttpOnly and Secure Cookies

If you store tokens in cookies, set these flags:

  • HttpOnly: Prevents JavaScript from reading the cookie (stops XSS attacks).
  • Secure: Ensures the cookie is only sent over HTTPS.
  • SameSite=Strict: Prevents CSRF (Cross-Site Request Forgery) attacks.

3. Handling JWTs (Tokens)

Keep Secrets Secret

Never hardcode your JWT_SECRET. Use environment variables (.env) and make sure .env is in your .gitignore.

Use Short Expiration Times

Tokens should not last forever. A good standard is 15 minutes to 1 hour for access tokens.

4. Protection Against Attacks

Rate Limiting

Prevent "Brute Force" attacks (where a bot tries thousands of passwords) by limiting how many requests an IP can make to your /login route.

rateLimiter.js
const rateLimit = require('express-rate-limit');

const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // Limit each IP to 5 login requests per window
message: "Too many login attempts, please try again after 15 minutes"
});

app.use('/api/auth/login', loginLimiter);

Generic Error Messages

Never tell a hacker which part of the login was wrong.

  • Bad: "User not found" or "Incorrect password."
  • Good: "Invalid email or password."

5. Multi-Factor Authentication (MFA)

For high-security apps, a password isn't enough. Implement MFA using:

  • TOTP: Apps like Google Authenticator.
  • Email/SMS: Sending a one-time code (OTP).

6. The "Master" Checklist

CategoryRequirementCheck
PasswordsHashed with Bcrypt + Salt
TransportAll traffic over HTTPS
TokensShort-lived + Securely stored
DatabaseRoles (RBAC) implemented
MonitoringLogs for failed login attempts

Practice: The Vulnerability Hunt

Go through your current project and check:

  1. Is your JWT_SECRET in a .env file?
  2. Do your login routes have a rate limiter?
  3. Are you using generic error messages?

If you answered "No" to any of these, now is the time to fix it!

Security Audits

Use tools like npm audit frequently. It will scan your project for libraries with known security holes and tell you how to patch them.