Node.js & Express

Rate Limiting & API Security

20 min Lesson 24 of 40

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:
  1. Implement rate limiting for different API endpoints
  2. Create API key authentication system with database storage
  3. Set up comprehensive input validation for a user registration endpoint
  4. Configure CORS for a multi-domain application
  5. Build a security middleware stack with Helmet, rate limiting, and sanitization