Authentication Best Practices
Authentication is fundamental to web security. Following best practices prevents common vulnerabilities and ensures user data protection.
Quick Navigation: Understanding Authentication Flow β’ Password Security β’ Session Management β’ Authentication Methods Comparison β’ Best Practices for Implementation
Quick Decision Guide
Quick Implementation Guide:
Password Hashing: Use bcrypt: const hash = await bcrypt.hash(password, 10). Never store plain passwords.
JWT Tokens: Use for stateless auth: jwt.sign({ userId }, SECRET, { expiresIn: '24h' }). Store in httpOnly cookie or localStorage (less secure).
Sessions: Use secure, httpOnly cookies: cookie: { secure: true, httpOnly: true, sameSite: 'strict' }
Rate Limiting: Prevent brute force: rateLimit({ windowMs: 15<em>60</em>1000, max: 5 }) on login endpoints.
Password Requirements: Minimum 8 chars, require complexity, check against common passwords list.
Security Checklist: - β Hash passwords with salt (bcrypt/Argon2) - β Use HTTPS only - β HttpOnly cookies for sessions - β Rate limit login attempts - β Regenerate session ID after login - β Set token expiration (24h max for JWTs)
Never: Store plain passwords, trust client validation, or put tokens in URLs.
Understanding Authentication Flow
Overview of Authentication
Authentication verifies who a user is. It's the process of confirming a user's identity before granting access to protected resources.
Figure 1: Authentication Flow
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β User β β Server β β Database β
β Browser β β β β β
ββββββββ¬βββββββ ββββββββ¬ββββββββ ββββββββ¬βββββββ
β β β
β 1. Submit Credentials β β
β (username/password)β β
ββββββββββββββββββββββββ> β
β β β
β β 2. Query User β
β βββββββββββββββββββββββββ>
β β β
β β <βββββββββββββββββββββββ
β β User Record β
β β β
β β 3. Verify Password β
β β (compare hash) β
β β β
β β β
β β 4. Generate Token/ β
β β Session β
β β β
β <βββββββββββββββββββββββ β
β Token/Session β β
β β β
β 5. Store Token β β
β (cookie/localStorage)β β
β β βAuthentication Methods
1. Password-Based Authentication
2. Token-Based Authentication (JWT)
3. OAuth 2.0
4. Multi-Factor Authentication (MFA)
Password Security
Never Store Plain Text Passwords
Figure 2: Password Storage Comparison
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Password Storage Methods β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β β Plain Text (DANGEROUS) β
β ββββββββββββββββββββββββββββββββββββββββ β
β β Password: "mypassword123" β β
β β Stored: "mypassword123" β β
β β β β
β β Risk: Immediate access if DB leaked β β
β ββββββββββββββββββββββββββββββββββββββββ β
β β
β β Basic Hashing (VULNERABLE) β
β ββββββββββββββββββββββββββββββββββββββββ β
β β Password: "mypassword123" β β
β β Hash: SHA256("mypassword123") β β
β β β β
β β Risk: Rainbow table attacks β β
β ββββββββββββββββββββββββββββββββββββββββ β
β β
β β
Salted Hashing (SECURE) β
β ββββββββββββββββββββββββββββββββββββββββ β
β β Password: "mypassword123" β β
β β Salt: "random_salt_abc123" β β
β β Hash: bcrypt(password + salt) β β
β β β β
β β Safe: Unique hash per password β β
β ββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββPassword Hashing Process
Figure 3: Password Hashing Flow
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β User β β Server β β Database β
β Registrationβ β β β β
ββββββββ¬βββββββ ββββββββ¬ββββββββ ββββββββ¬βββββββ
β β β
β 1. Submit Password β β
ββββββββββββββββββββββββ> β
β β β
β β 2. Generate Salt β
β β (random) β
β β β
β β 3. Hash Password β
β β bcrypt(password + salt)β
β β β
β β 4. Store Hash + Salt β
β βββββββββββββββββββββββββ>
β β β
β <βββββββββββββββββββββββ β
β Success β β
β β βUse Hashing Algorithm:
Salt Passwords:
Password Requirements
Session Management
Session vs Token-Based Authentication
Figure 4: Session-Based Authentication Flow
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β User β β Server β β Session β
β Browser β β β β Store β
ββββββββ¬βββββββ ββββββββ¬ββββββββ ββββββββ¬βββββββ
β β β
β 1. Login β β
ββββββββββββββββββββββββ> β
β β β
β β 2. Create Session β
β βββββββββββββββββββββββββ>
β β β
β β <βββββββββββββββββββββββ
β β Session ID β
β β β
β <βββββββββββββββββββββββ β
β Session Cookie β β
β (sessionId) β β
β β β
β 3. Request with Cookieβ β
ββββββββββββββββββββββββ> β
β β β
β β 4. Validate Session β
β βββββββββββββββββββββββββ>
β β β
β β <βββββββββββββββββββββββ
β β Session Data β
β β β
β <βββββββββββββββββββββββ β
β Authorized β β
β β βFigure 5: Token-Based Authentication Flow (JWT)
βββββββββββββββ ββββββββββββββββ
β User β β Server β
β Browser β β β
ββββββββ¬βββββββ ββββββββ¬ββββββββ
β β
β 1. Login β
ββββββββββββββββββββββββ>
β β
β β 2. Generate JWT β
β β (signed token) β
β β β
β <βββββββββββββββββββββββ β
β JWT Token β β
β (contains user info)β β
β β β
β 3. Store Token β β
β (localStorage/cookie)β β
β β β
β 4. Request with Token β β
ββββββββββββββββββββββββ> β
β β β
β β 5. Verify Token β
β β (check signature) β
β β β
β <βββββββββββββββββββββββ β
β Authorized β β
β β β| Aspect | Server-Side Sessions | Token-Based (JWT) |
|---|---|---|
| Storage | Server-side | Client-side |
| Scalability | Requires shared storage | Stateless |
| Revocation | Easy (delete session) | Hard (wait for expiry) |
| Security | More secure | Less secure (if stolen) |
| Use Case | Traditional apps | Microservices, APIs |
res.cookie('session', sessionId, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 24 * 60 * 60 * 1000 // 24 hours
});Authentication Methods Comparison
| Method | Security | Complexity | Use Case |
|---|---|---|---|
| Password-Based | βββ Medium | Low | Most common, simple apps |
| JWT Tokens | ββββ High | Medium | APIs, microservices |
| OAuth 2.0 | βββββ Highest | High | Third-party login |
| MFA | βββββ Highest | High | Sensitive accounts |
Best Practices for Implementation
Security Checklist
Password Security:
Rate Limiting:
Session Management:
Token Security:
General Security:
Common Mistakes to Avoid
Mistake 1: Storing plain text passwords
password: "mypassword123"passwordHash: bcrypt.hash("mypassword123", salt)Mistake 2: Not rate limiting login
Mistake 3: Weak session management
httpOnly: true, secure: true, sameSite: 'strict'Mistake 4: Long-lived tokens
Mistake 5: Trusting client validation