Solución:
Entonces, después de buscar un poco, no pude encontrar una solución que me gustara, así que escribí la mía propia basada en la solución de Trevor y expresamente en bruto. Lo puedes encontrar aquí.
Tal vez algo como esto pueda ayudarlo a comenzar.
var failures = {};
function tryToLogin() {
var f = failures[remoteIp];
if (f && Date.now() < f.nextTry) {
// Throttled. Can't try yet.
return res.error();
}
// Otherwise do login
...
}
function onLoginFail() {
var f = failures[remoteIp] = failures[remoteIp] || {count: 0, nextTry: new Date()};
++f.count;
f.nextTry.setTime(Date.now() + 2000 * f.count); // Wait another two seconds for every failed attempt
}
function onLoginSuccess() { delete failures[remoteIp]; }
// Clean up people that have given up
var MINS10 = 600000, MINS30 = 3 * MINS10;
setInterval(function() {
for (var ip in failures) {
if (Date.now() - failures[ip].nextTry > MINS10) {
delete failures[ip];
}
}
}, MINS30);
paquete rate-limiter-flexible con Redis o Mongo para aplicaciones distribuidas y en memoria o con ayudas de Cluster
Aquí hay un ejemplo con Redis
const { RateLimiterRedis } = require('rate-limiter-flexible');
const Redis = require('ioredis');
const redisClient = new Redis({
options: {
enableOfflineQueue: false
}
});
const opts = {
redis: redisClient,
points: 5, // 5 points
duration: 15 * 60, // Per 15 minutes
blockDuration: 15 * 60, // block for 15 minutes if more than points consumed
};
const rateLimiter = new RateLimiterRedis(opts);
app.post('/auth', (req, res, next) => {
const loggedIn = loginUser();
if (!loggedIn) {
// Consume 1 point for each failed login attempt
rateLimiter.consume(req.connection.remoteAddress)
.then((data) => {
// Message to user
res.status(400).send(data.remainingPoints + ' attempts left');
})
.catch((rejRes) => {
// Blocked
const secBeforeNext = Math.ceil(rejRes.msBeforeNext / 1000) || 1;
res.set('Retry-After', String(secBeforeNext));
res.status(429).send('Too Many Requests');
});
} else {
// successful login
}
});
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)