ExpressJS - 速率限制
在 Express.js 中实现请求限流
Section titled “在 Express.js 中实现请求限流”请求限流(Rate Limiting)是 Web 应用程序一项至关重要的安全和性能技术。它限制了用户(或 IP 地址)在给定时间段内可以发出的请求数量。这有助于防止滥用,例如:
- 拒绝服务 (DoS) 攻击:通过过多请求使服务器过载,降低合法用户的性能。
- 暴力破解攻击:反复尝试猜测登录或密码重置端点上的凭据。
- 网络爬虫:阻止机器人程序从您的网站上恶意抓取内容。
使用 express-rate-limit
Section titled “使用 express-rate-limit”express-rate-limit 中间件是 Express 中实现请求限流的行业标准。它高度可配置且易于使用。主要选项包括:
windowMs:检查请求的时间范围,以毫秒为单位。例如,15 * 60 * 1000设置一个 15 分钟的窗口。max(或limit):在windowMs期间允许来自单个 IP 的最大连接数。一旦超出限制,后续请求将被拒绝,并返回429 Too Many Requests状态码。message:超出限制时发送的错误消息。可以是字符串、JSON 对象或函数。standardHeaders:一个布尔值(true),用于启用标准化的RateLimit-*响应头。legacyHeaders:一个布尔值(false),用于禁用旧的、非标准的X-RateLimit-*头。
使用 npm 或您偏好的包管理器安装依赖。
npm install express-rate-limit以下代码设置了一个全局请求限流器,允许每个 IP 每 15 分钟发送 100 个请求。它还展示了如何专门针对身份验证路由创建更严格的限流器。
import express from 'express';import rateLimit from 'express-rate-limit';
const app = express();const PORT = 3000;
// 创建一个通用请求限流器const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 分钟 limit: 100, // 限制每个 IP 在每个“窗口”(这里是每 15 分钟)内发送 100 个请求 standardHeaders: 'draft-7', // 使用标准的 `RateLimit` 头语法 legacyHeaders: false, // 不发送 `X-RateLimit-*` 头 message: { error: 'Too many requests, please try again after 15 minutes.' },});
// 为登录等敏感端点创建更严格的请求限流器const loginLimiter = rateLimit({ windowMs: 10 * 60 * 1000, // 10 分钟 limit: 5, // 限制每个 IP 在每个“窗口”内尝试登录 5 次 message: { error: 'Too many login attempts, please try again after 10 minutes.' }, standardHeaders: 'draft-7', legacyHeaders: false,});
// 将通用限流器应用于所有对 `/api` 的请求app.use('/api', apiLimiter);
// 一个常规的 API 路由app.get('/api/data', (req, res) => { res.send('This is public data.');});
// 仅将更严格的限流器应用于登录路由app.post('/api/login', loginLimiter, (req, res) => { // ... 登录逻辑在此 ... res.send('Login attempt recorded.');});
app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`);});测试请求限流器
Section titled “测试请求限流器”- 运行服务器(例如,使用
npm run dev)。 - 在 10 分钟内向
http://localhost:3000/api/login发送超过 5 次POST请求。在第 6 次请求时,您将收到一个429 Too Many Requests响应以及您自定义的 JSON 错误消息。 - 响应头将包括
RateLimit-Limit(最大请求数)、RateLimit-Remaining(剩余请求数)和RateLimit-Reset(限流重置的时间戳)。