如何根据用户登录状态配置express-rate-limit动态限流规则?
实现方案
你的代码有3个核心问题需要修正:
- 语法错误:对象配置项的
max字段不能直接写if语句作为值,要么用条件判断返回值,要么使用中间件提供的专用配置 - 作用域错误:你定义在路由处理函数里的
user变量,限流中间件执行时根本访问不到,必须从请求对象req上获取对应数据 - 顺序错误:如果要从
req.body读取user字段,必须先注册JSON请求体解析中间件,再挂载限流中间件,否则req.body会是undefined,判断逻辑永远不生效
推荐实现(用skip配置直接跳过登录用户限流)
express-rate-limit原生提供skip配置项,返回true的请求会直接绕过限流逻辑,不会产生限流计数,性能比动态修改max更好:
// 首先注册body解析中间件,必须放在限流、业务路由之前 app.use(express.json()) const limiter = rateLimit({ windowMs: 24 * 60 * 60 * 1000, // 24小时计数窗口 max: 10, // 匿名用户单窗口最多允许10次请求 standardHeaders: true, legacyHeaders: false, // 跳过限流规则:请求携带真值user时,不做限流 skip: (req) => Boolean(req.body?.user) }) // 再挂载限流中间件 app.use('/link', limiter) // 最后写业务路由 app.post("/link", async (req, res) => { const premiumLink = req.body.downloadLink; const password = req.body.password; const user = req.body.user; // 后续业务逻辑 })
备选实现(动态返回max值)
如果你不想用skip,也可以给max传入函数动态返回允许的请求数,给已识别的用户返回一个足够大的数值即可(注意不要返回0,返回0代表该类请求允许次数为0,会直接被全部拦截):
const limiter = rateLimit({ windowMs: 24 * 60 * 60 * 1000, // 动态返回最大请求数 max: (req) => { return req.body?.user ? Number.MAX_SAFE_INTEGER : 10 }, standardHeaders: true, legacyHeaders: false, })
注意:实际生产环境不建议直接从
req.body取用户身份做判断,很容易被伪造请求绕过限制,建议先经过鉴权中间件解析JWT/Session,把合法用户信息挂在req.user上,再在skip逻辑里判断req.user即可。
内容的提问来源于stack exchange,提问作者user18106703
相关产品推荐
相关产品推荐

