Topic 48 of 55
Request Rate Limiting Defense
Overview
Rate limiting restricts the number of requests a single client (usually identified by IP address) can make to your server within a specific timeframe. This defends against brute-force attacks (like password guessing) and Denial of Service (DoS) attacks.
Syntax
javascript
// 1. Install express-rate-limit
// npm install express-rate-limit
const rateLimit = require('express-rate-limit');
// 2. Create a limiter
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes window
max: 100, // Limit each IP to 100 requests per windowMs
message: "Too many requests from this IP, please try again after 15 minutes",
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
});
// 3. Apply it to all requests
app.use(limiter);Common Pitfalls
- If your Node app is running behind a proxy or load balancer (like Nginx, AWS ELB, or Heroku), all requests will appear to come from the proxy's IP. You MUST enable `app.set('trust proxy', 1)` for rate limiting to work correctly.
- In a clustered environment (multiple servers), storing rate-limit state in memory won't work. You need to use a shared store like Redis.
Real-World Example
Applying strict rate limits to sensitive routes like Login:
example
javascript
const rateLimit = require('express-rate-limit');
// Global API limiter (generous)
const apiLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 200
});
app.use('/api/', apiLimiter);
// Strict login limiter (prevents brute forcing passwords)
const loginLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 hour window
max: 5, // Start blocking after 5 requests
message: "Too many failed login attempts, account locked for 1 hour"
});
// Apply only to the login route
app.post('/api/login', loginLimiter, (req, res) => {
// Login logic...
});