fix(ratelimit): 全局限流改为优先按用户分桶并按 1200/分放宽,避免反代未透传 XFF 时全站误伤

这个提交包含在:
xcbyy
2026-10-19 13:51:27 +08:00
父节点 25d8474877
当前提交 0752acda40
共有 2 个文件被更改,包括 9 次插入 和 3 次删除

查看文件

@@ -148,7 +148,12 @@ MYSQL_DATABASE=peiwan
6. 订阅消息为**一次性**:用户授权一次只能收 1 条;高频场景需每次动作前请求授权(代码已在下单/报名/提现前请求)。
### 限流与错误信息(已内置,无需额外配置)
- **全局限流**:`/api` 每 IP 600 次/分钟;**写接口单独限流**:发帖 10/分、评论 20/分、组局申请 20/分、举报 5/分、上传 30/分、下单 20/分、支付下单 30/分、充值/提现 10/分、浏览 1 次/3 秒(同 IP+动态)。超限返回 HTTP `429` + `Retry-After`。
- **全局限流**:`/api` 每**用户**(未登录按 IP)1200 次/分钟;**写接口单独限流**:发帖 10/分、评论 20/分、组局申请 20/分、举报 5/分、上传 30/分、下单 20/分、支付下单 30/分、充值/提现 10/分、浏览 1 次/3 秒(同 IP+动态)。超限返回 HTTP `429` + `Retry-After`。
- ⚠️ **反向代理务必透传真实客户端 IP**,否则限流会把所有用户并成一个 IP 桶:
```nginx
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
```
- **5xx 脱敏**:服务端 5xx 只记录日志,对外统一返回「服务器内部错误,请稍后重试」,不再回传 SQL/堆栈等内部细节。
- 限流为**单实例内存级**;多实例部署时如需跨实例统一限流,需改用 Redis 计数(可选)。

查看文件

@@ -109,8 +109,9 @@ function rateLimit(opts: { name: string; windowMs: number; max: number; key?: (r
};
}
// 全局限流(宽松,主要抵御暴力刷接口/爬取)
app.use('/api', rateLimit({ name: 'global', windowMs: 60 * 1000, max: 600 }));
// 全局限流(宽松,主要抵御暴力刷接口/爬取)。优先按登录用户分桶,未登录退化到 IP,
// 避免反向代理未透传 X-Forwarded-For 时全站用户共用同一 IP 桶被误伤。
app.use('/api', rateLimit({ name: 'global', windowMs: 60 * 1000, max: 1200, key: rateWriteKey }));
// 写接口限流键:优先按登录用户,未登录退化到 IP
function rateWriteKey(req: Request): string {