在Express.js应用程序中,我们希望对经常访问某个路由的用户进行速率限制,但前提是它们会导致某种异常。在Express中有自然的方法吗?
这或多或少是我们现在所拥有的,而不是速率限制。
app.get(
"/api/method",
authenticationMiddleware,
handler
);
速率限制器中间件通常看起来像这样。它会计算访问次数,如果用户在访问处理程序之前访问了很多次,则会出错。
app.get(
"/api/method",
authenticationMiddleware,
rateLimiterMiddleware, # <--- count, and tell them to go away if over limit
handler
);
但是,我们很好,他们可以随心所欲地访问它 - 我们只是想禁止他们,如果他们最近造成了很多例外。
在Express中,错误处理程序应该位于处理程序链的末尾。
因此,似乎我们必须将“警卫”放在前面,并在最后处理错误处理“计数器”。
app.get(
"/api/method",
authenticationMiddleware,
errorIfTooManyExceptionsByUser, # <--- tell them to go away if over the limit
handler,
countExceptionsForUser # <--- count
);
这似乎不够优雅,而且有点棘手,因为速率限制中间件的两个部分必须彼此了解很多。有没有更好的办法?
也许我们可以聪明地修改处理程序,在它们运行之前和之后进行防护和计数?
app.get(
"/api/method",
authenticationMiddleware,
rateLimitErrors(handler) # <-- ???
)
我错过了什么或者有更好的方法吗?
你可以看看express-redis-cache
如何处理他的中间件(https://github.com/rv-kip/express-redis-cache/blob/df4ed8e057a5b7d41d894e6e468f975aa62206f6/lib/ExpressRedisCache/route.js#L184)。他们用自己的逻辑包装了表达的send()
方法。也许有这个你只能有一个中间件,但我认为这不是最好的解决方案。
现有的中间件在快递https://www.npmjs.com/package/express-rate-limit中处理速率限制。
Express是一个轻量级框架,在官方文档中他们建议将Nginx放在快递服务器前面来处理服务器事务。
(Qazxswpoi)
Use a reverse proxy
除了将请求定向到应用程序之外,反向代理位于Web应用程序前面并对请求执行支持操作。它可以处理错误页面,压缩,缓存,提供文件和负载平衡等。
将不需要应用程序状态知识的任务移交给反向代理可以释放Express以执行专门的应用程序任务。出于这个原因,建议在生产中在Nginx或HAProxy之类的反向代理后面运行Express。
在nginx中你有一个限速系统:https://expressjs.com/en/advanced/best-practice-performance.html。我不知道您是否可以根据具体用例自定义此功能,但我认为这是处理速率限制的最佳方式。