Security First
Authentication and authorization are the foundation of application security. Get them wrong, and you expose user data and system resources. Get them right, and you build trust while protecting your platform.
Authentication Methods
Password-Based Authentication
Still the most common method:
- Hashing: Use bcrypt, Argon2, or scrypt
- Salt: Unique salt per password
- Strength requirements: Enforce strong passwords
- Password reset: Secure reset flow
- Rate limiting: Prevent brute force attacks
OAuth 2.0 / OpenID Connect
Social login integration:
- Google, GitHub, etc.: Popular providers
- Authorization code flow: Most secure
- PKCE: For mobile and SPAs
- Token validation: Always verify tokens
- User profile mapping: Handle provider differences
Multi-Factor Authentication (MFA)
Add an extra security layer:
- TOTP: Time-based one-time passwords (Google Authenticator)
- SMS OTP: One-time codes via SMS
- Email OTP: Codes sent via email
- Hardware tokens: YubiKey, etc.
- Backup codes: For account recovery
JWT Implementation
Token Structure
JWTs consist of three parts:
- Header: Algorithm and token type
- Payload: Claims (user data)
- Signature: Cryptographic signature
Best Practices
// Token generation
const token = jwt.sign(
{
userId: user.id,
email: user.email,
role: user.role
},
secretKey,
{
expiresIn: '15m', // Short-lived access token
issuer: 'your-app',
audience: 'your-app'
}
);
// Refresh token (longer-lived, stored securely)
const refreshToken = jwt.sign(
{ userId: user.id, type: 'refresh' },
refreshSecret,
{ expiresIn: '7d' }
);
Token Rotation
Implement refresh token rotation:
- Issue refresh token with access token
- Store refresh token securely (httpOnly cookie or database)
- Rotate on use: Issue new refresh token, invalidate old
- Detect theft: Multiple uses of same refresh token = compromise
Role-Based Access Control (RBAC)
Role Hierarchy
Design role structure:
- Super Admin: Full system access
- Admin: Manage users and content
- Moderator: Content moderation
- User: Standard user access
- Guest: Limited read access
Permission System
Granular permissions:
const permissions = {
'users:read': ['admin', 'moderator'],
'users:write': ['admin'],
'content:read': ['admin', 'moderator', 'user'],
'content:write': ['admin', 'moderator'],
'settings:read': ['admin'],
'settings:write': ['admin']
};
const hasPermission = (user, permission) => {
return permissions[permission]?.includes(user.role);
};
Implementation
// Middleware for route protection
const requirePermission = (permission) => {
return (req, res, next) => {
if (!hasPermission(req.user, permission)) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
};
// Usage
app.get('/admin/users',
authenticate,
requirePermission('users:read'),
getUsers
);
Session Management
Session Storage
Choose storage method:
- Database: Most control, requires cleanup
- Redis: Fast, scalable, TTL support
- JWT: Stateless, but harder to revoke
- Cookies: Simple, but limited size
Security Considerations
- HttpOnly cookies: Prevent XSS attacks
- Secure flag: HTTPS only
- SameSite: CSRF protection
- Session timeout: Automatic expiration
- Concurrent sessions: Limit or allow multiple
Password Security
Hashing
Never store plaintext passwords:
const bcrypt = require('bcrypt');
// Hash password
const hashedPassword = await bcrypt.hash(password, 12);
// Verify password
const isValid = await bcrypt.compare(password, hashedPassword);
Password Policies
Enforce strong passwords:
- Minimum length: 8+ characters
- Complexity: Mix of character types
- Common passwords: Block common passwords
- Password history: Prevent reuse
- Expiration: Optional, often annoying
API Authentication
API Keys
For programmatic access:
- Generate securely: Cryptographically random
- Scope permissions: Limit what keys can do
- Rate limiting: Prevent abuse
- Rotation policy: Regular key rotation
- Revocation: Ability to disable keys
Bearer Tokens
For user-initiated API access:
- Short expiration: 15-60 minutes
- Refresh tokens: For long-lived sessions
- Token revocation: Ability to invalidate
- Scope-based: Limit token permissions
Security Best Practices
Common Vulnerabilities
Protect against:
- SQL Injection: Parameterized queries
- XSS: Input sanitization
- CSRF: Token validation
- Session fixation: Regenerate on login
- Timing attacks: Constant-time comparisons
Rate Limiting
Prevent abuse:
- Login attempts: Limit failed logins
- Password reset: Prevent enumeration
- API calls: Rate limit endpoints
- IP-based: Block suspicious IPs
Real-World Implementation
For a multi-tenant SaaS platform, I built:
- JWT authentication: Access and refresh tokens
- OAuth integration: Google, GitHub login
- MFA support: TOTP and SMS OTP
- RBAC system: Roles and permissions
- Session management: Redis-based sessions
- API authentication: API keys and bearer tokens
- Rate limiting: Per-user and per-IP limits
Security features:
- Password hashing: bcrypt with salt
- Token rotation: Refresh token rotation
- Audit logging: All auth events logged
- Anomaly detection: Unusual login patterns
- Account lockout: After failed attempts
Results:
- Zero security breaches in production
- 99.9% uptime for auth service
- < 200ms average auth response time
- Seamless user experience with SSO
Key Takeaways
- Never trust client input: Validate and sanitize everything
- Use established libraries: Don't roll your own crypto
- Implement defense in depth: Multiple security layers
- Monitor and log: Detect attacks early
- Keep dependencies updated: Security patches matter
- Test security: Regular security audits
- Document security: Security decisions need documentation
Authentication and authorization are complex, but following security best practices and using established patterns makes building secure systems achievable. The key is understanding threats and implementing appropriate defenses at every layer.
