为什么express-rate-limit中间件不在同一文件定义时无法正常生效?
失效原因
express-rate-limit的限流计数器与rateLimit()生成的实例绑定,每个实例独立维护请求计数,只有复用同一个实例才能实现跨请求的限流统计,两个场景的核心差异如下:
- 场景1中
limiter实例在middleware.ts顶层作用域初始化,属于模块级单例,应用生命周期内仅创建一次,所有请求复用同一个实例计数,因此限流正常生效。 - 场景2中
limiter实例的创建逻辑放在了请求处理流程内部,每次收到新请求都会生成全新的limiter实例,每个实例的计数都从0开始,永远不会触发max=5的限流阈值,因此功能失效。
修复方案
将limiter的初始化逻辑移到login.ts的顶层作用域即可,同时你场景2的原代码还缺少请求处理函数的外层包裹,完整修复代码如下:
import { NextApiRequest, NextApiResponse } from 'next' import rateLimit from 'express-rate-limit' import { runMiddleware } from '../../lib/middleware' // 顶层作用域初始化,全局仅创建一次 const limiter = rateLimit({ keyGenerator: function (req: any) { return req.headers["x-forwarded-for"] || req.connection.remoteAddress; }, windowMs: 60 * 1000, // 1分钟 max: 5, // 单IP最多5次请求 }) module.exports = async (req: NextApiRequest, res: NextApiResponse) => { try { await runMiddleware(req, res, limiter) } catch { res.status(500) res.end(JSON.stringify({errorCode: 'unknown', errorValue: ''})) return } if (req.method === 'POST') { res.status(200) res.end(JSON.stringify({errorCode: 'ok', errorValue: ''})) } }
内容的提问来源于stack exchange,提问作者Sylvain
相关产品推荐
相关产品推荐

