我可以使用express-rate-limit为同一条路线设置多个速率限制吗?

cbd*_*per 4 node.js express express-rate-limit

我可以为我的 Express 服务器设置全局rateLimit,并rateLimit为某些路由设置更严格的限制吗?

例如:

const globalLimit = rateLimit({
  windowMs: 60 * 60 * 1000,        // 1 HOUR
  max: 500                         // MAX 500 REQUESTS
});

const apiLimit = rateLimit({
  windowMs: 60 * 60 * 1000,        // 1 HOUR
  max: 100                         // MAX 100 REQUESTS
});

const someRouteLimit = rateLimit({
  windowMs: 60 * 60 * 1000,        // 1 HOUR
  max: 10                          // MAX 10 REQUESTS
});


app.use("/", globalLimit);         // ALL ROUTES WILL BE LIMITED BY THE globalLimit
app.use("/api", apiLimit);         // API ROUTES WILL BE LIMITED BY THE apiLimit

app.get("/some-route", someRouteLimit, routeHandler);  // THIS ROUTE WILL BE LIMITED BY THE someRouteLimit
Run Code Online (Sandbox Code Playgroud)

它会按照我想要的方式工作吗?这是包的正常使用express-rate-limit还是反模式?

Avi*_* Lo 5

express-rate-limit是一个相当受欢迎的包。所以我不认为这是一种反模式。

中间件可以链接起来。

例如,您想将someRouteLimitapiLimit强加于/some-route

app.get("/some-route",apiLimit,someRouteLimit,routeHandler)
Run Code Online (Sandbox Code Playgroud)

中间件是按顺序执行的,因此您希望将限制性较强的中间件放在限制性较宽松的中间件之后。

Express中间件层次结构:

  1. 应用层中间件
  2. 路由器级中间件

app.use("/", globalLimit)是一个应用程序级中间件,因此它将在所有其他中间件之前首先执行,但在其他应用程序级中间件之前/之后执行,具体取决于它们的调用顺序。

您还可以使用路由器对路由进行分组,并在特定路由器上应用速率限制中间件。

在你的app.jsindex.js

// Depedencies
const express = require('express')
const rateLimit = require('express-rate-limit')

// Initialize the app
const app = express()

const globalLimit = rateLimit({
  windowMs: 60 * 60 * 1000,        // 1 HOUR
  max: 500                         // MAX 500 REQUESTS
});

const apiLimit = rateLimit({
  windowMs: 60 * 60 * 1000,        // 1 HOUR
  max: 100                         // MAX 100 REQUESTS
});


// Load Routes
const routeOne = require('./routes/routeOne');
const routeTwo = require('./routes/routeTwo');

// Use routes
app.use('/', routeOne,apiLimit); // Impose apiLimit on this router
app.use('/', routeTwo);          // No router-level middleware is applied

app.listen(portNumber)
Run Code Online (Sandbox Code Playgroud)

在routeOne中:(同时受globalLimit和限制apiLimit

const express = require('express');
const router = express.Router();
const rateLimit = require('express-rate-limit')

const someRouteLimit = rateLimit({
  windowMs: 60 * 60 * 1000,        // 1 HOUR
  max: 10                          // MAX 10 REQUESTS
});


// Some Route (further restricted by someRouteLimit)
router.post('/some-route',someRouteLimit, routeHandler);

module.exports = router;

Run Code Online (Sandbox Code Playgroud)

在 RouteTwo 中:(受globalLimit但不受限制apiLimit

const express = require('express');
const router = express.Router();
const rateLimit = require('express-rate-limit')

const someRouteLimit2 = rateLimit({
  windowMs: 60 * 60 * 1000,        // 1 HOUR
  max: 10                          // MAX 10 REQUESTS
});


// Some Route (further restricted by someRouteLimit2)
router.post('/some-route2',someRouteLimit, routeHandler);

module.exports = router;
Run Code Online (Sandbox Code Playgroud)

如果您想以更加自定义的方式实现中间件,本文中还有一些使用正则表达式和自定义帮助函数的更具创意的方法。