在Node js中使用express-rat-limit后,如何增加阻塞时间段?express-rate-limit
库会在每个时间单位超过一定数量的请求后,阻止来自客户端的连接(比如说通过IP识别)。它还会在与时间单位相当的时间内阻止连接。
所以,如果设置为每分钟120个请求后阻止连接;它也会阻止该IP一分钟。如何延长封堵时间?
这是我现在的例子。
...
var express = require('express');
var app = express();
const RateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
limiter = new RateLimit({
store: new RedisStore({
expiry: 60
}),
max: 120
});
app.use(limiter);
...
这里,我也使用了 rate-limit-redis
,其 expiry
参数会覆盖 windowMs
的参数 express-rate-limit
.
通过使用 onLimitReached
回调,你可以保留IP再次被解封的时间记录。然后,你可以再写一个中间件,检查何时达到解封日期。
在下面的例子中。bannedIPs
保存IP再次被解封的时间记录,并且 banner
是中间件,根据当前日期,利用时间来封锁IP。
...
var express = require('express');
var app = express();
const RateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
// Keep the IPs that are banned
const bannedIPs = {};
limiter = new RateLimit({
store: new RedisStore({
expiry: 60
}),
onLimitReached: function(req, res, options) {
// The IP will be unblocked again in an hour (60*60*1000)
bannedIPs[req.ip] = +new Date() + 60*60*1000;
},
max: 120
});
banner = function(req, res, next) {
// If the current Date is still before than the unblocking date,
// send a 429 message indicating too many requests
if (bannedIPs[req.ip] >= +new Date()) {
res.status(429).send("Sorry, too many requests: " + new Date(bannedIPs[req.ip]));
} else {
next();
}
}
app.use(banner);
app.use(limiter);
...
有很多改进的空间,比如一旦不再封IP,就把IP删除,也许可以把密钥存储在Redis中,这样重启服务器后,密钥就会持久存在。但是,这能给你一个起点。