Node.js & Express
Rate Limiting & API Security
Rate Limiting & API Security
Protecting your API from abuse and attacks is crucial for maintaining service availability and security. Rate limiting and implementing security best practices help prevent malicious activities and ensure fair resource usage among all users.
Understanding Rate Limiting
Rate limiting controls how many requests a user or IP address can make to your API within a specific time window:
Why Rate Limiting?
- Prevent DDoS attacks and abuse
- Ensure fair API usage across all users
- Protect against brute-force attacks
- Control costs for third-party API usage
- Maintain service availability and performance
- Comply with infrastructure resource limits
Implementing Rate Limiting with express-rate-limit
Install the express-rate-limit package:
npm install express-rate-limit
Basic rate limiting setup:
const express = require('express');
const rateLimit = require('express-rate-limit');
const app = express();
// Create a rate limiter
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP, please try again later.',
standardHeaders: true, // Return rate limit info in `RateLimit-*` headers
legacyHeaders: false, // Disable `X-RateLimit-*` headers
});
// Apply to all routes
app.use(limiter);
// Or apply to specific routes
app.use('/api/', limiter);
app.listen(3000);
Creating multiple rate limiters for different endpoints:
const express = require('express');
const rateLimit = require('express-rate-limit');
const app = express();
// Strict limiter for authentication endpoints
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // 5 attempts
skipSuccessfulRequests: true, // Don't count successful requests
message: 'Too many login attempts, please try again later'
});
// General API limiter
const apiLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 60, // 60 requests per minute
message: 'Rate limit exceeded'
});
// Strict limiter for resource-intensive operations
const heavyLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 1 hour
max: 10, // 10 requests per hour
message: 'Too many requests for this resource'
});
// Apply different limiters
app.post('/auth/login', authLimiter, loginHandler);
app.post('/auth/register', authLimiter, registerHandler);
app.use('/api/', apiLimiter);
app.post('/api/reports/generate', heavyLimiter, generateReportHandler);
Security Best Practices:
- Never commit API keys or secrets to version control
- Use environment variables for sensitive configuration
- Keep dependencies updated (use npm audit)
- Implement proper authentication and authorization
- Log security events for monitoring and auditing
- Use HTTPS in production (enforce with HSTS)
- Implement request timeouts to prevent resource exhaustion
- Regular security audits and penetration testing
Practice Exercise:
- Implement rate limiting for different API endpoints
- Create API key authentication system with database storage
- Set up comprehensive input validation for a user registration endpoint
- Configure CORS for a multi-domain application
- Build a security middleware stack with Helmet, rate limiting, and sanitization