如何正确使用.get()并在express应用程序中灵活设置费率限制



我正试图将速率限制纳入我的网站,以防止暴力,同时防止帐户被随机用户锁定。我阅读这篇文章是为了了解它的基本工作原理,但代码对我来说不起作用。我浏览了文档,但找不到任何关于我所遇到的错误的内容,在其他地方也找不到。

import { createClient } from 'redis';
import { RateLimiterRedis } from 'rate-limiter-flexible';
const maxWrongAttemptsByIPperMinute = 6;
const maxWrongAttemptsByIPperDay = 100;
const maxConsecutiveFailsByEmailAndIP = 12;
const redisPort = 6379;
const redisClient = createClient({
host: 'redis',
port: redisPort,
enable_offline_queue: false,
});
redisClient.on('error', (err) => console.log('Redis Client Error', err));
// Limit attempts by ip throughout the day
export const limiterSlowBruteByIP = new RateLimiterRedis({
redis: redisClient,
keyPrefix: 'login_fail_ip_per_day',
points: maxWrongAttemptsByIPperDay,
duration: 60 * 60 * 24,
blockDuration: 60 * 60 * 24 // Block for 1 day on 100 failed attempts per day
});
// Limit attempts by ip on a minute basis
export const limiterFastBruteByIP = new RateLimiterRedis({
redis: redisClient,
keyPrefix: 'login_fail_ip_per_minute',
points: maxWrongAttemptsByIPperMinute,
duration: 30,
blockDuration: 60 * 5, // Block ip for 5 minutes if 6 wrong attempts within 30 seconds
});
// Limit attempts by username and ip combo within 90 days
export const limiterConsecutiveFailsByEmailAndIP = new RateLimiterRedis({
redis: redisClient,
keyPrefix: 'login_fail_consecustive_username_and_ip',
points: maxConsecutiveFailsByEmailAndIP,
duration: 60 * 60 * 24 * 90, // Store number for 90 days since first fail
blockDuration: 60 * 60 * 24 * 365 // Block forever after max consecustive fails
});
// Get email and ip combination
export const getEmailIPkey = (email, ip) => `${email}_${ip}`;
export const loginRateLimitChecker = async (req, res, next) => {
const ipAddr = req.connection.remoteAddress;
const emailIPkey = getEmailIPkey(req.body.email, ipAddr);
const test = await limiterConsecutiveFailsByEmailAndIP.get(emailIPkey);
console.log('here');

我只包含了错误发生之前的代码,因为其余的暂时无关紧要。我收到的错误来自.get((,无法访问console.log。

.pttl(rlKey)
^
TypeError: this.client.multi(...).get(...).pttl is not a function

根据官方文件,检查费率限制的方法是.consume


const rateLimiterMiddleware = (req, res, next) => {
rateLimiter.consume(req.ip)
.then(() => {
next();
})
.catch(() => {
res.status(429).send('Too Many Requests');
});
};

基于此尝试修复您的代码:

export const loginRateLimitChecker = async (req, res, next) => {
const ipAddr = req.connection.remoteAddress;
const email = req.body && req.body.email ? req.body.email : 'n/a';
const emailIPkey = getEmailIPkey(email, ipAddr);
try {
const test = await limiterConsecutiveFailsByEmailAndIP.consume(emailIPkey);
}
catch (error) {
res.status(429).send('Too Many Requests');
console.log(`Request rate-limited by key ${emailIPkey}`);
return;
}
next();    
});

最新更新