在Express应用中正确使用rate-limit-flexible的.get()方法的问题
解决RateLimiterRedis调用get()时的pttl函数错误
错误原因
你遇到的TypeError: this.client.multi(...).get(...).pttl is not a function是因为:
- 使用了Redis客户端v4+版本,该版本API与旧版(v3及以下)不兼容,
multi()返回的对象不再支持链式调用get().pttl()的写法; - 代码中未显式调用Redis客户端的
connect()方法,客户端未建立连接导致命令无法正常执行。
解决方案
方案1:适配Redis v4客户端(推荐,无需降级)
rate-limiter-flexible支持Redis v4,但需要调整客户端传递方式并确保连接完成:
- 修改Redis客户端创建代码,添加连接逻辑:
import { createClient } from 'redis'; import { RateLimiterRedis } from 'rate-limiter-flexible'; // ...其他常量定义 const redisClient = createClient({ host: 'redis', port: redisPort, enable_offline_queue: false, }); redisClient.on('error', (err) => console.log('Redis Client Error', err)); // 显式建立Redis连接 await redisClient.connect();
- 创建RateLimiter实例时,用
sendCommand替代直接传递redis客户端:
// Limit attempts by ip throughout the day export const limiterSlowBruteByIP = new RateLimiterRedis({ sendCommand: (...args) => redisClient.sendCommand(args), // 替换原redis: redisClient keyPrefix: 'login_fail_ip_per_day', points: maxWrongAttemptsByIPperDay, duration: 60 * 60 * 24, blockDuration: 60 * 60 * 24 }); // 其余两个限流器(limiterFastBruteByIP、limiterConsecutiveFailsByEmailAndIP)做同样修改
- 确保
loginRateLimitChecker函数在Redis连接完成后执行,可将连接逻辑放在项目入口文件提前初始化。
方案2:降级到Redis客户端v3版本
若不想修改过多代码,可降级到兼容的旧版本:
- 卸载当前Redis包:
npm uninstall redis
- 安装v3版本:
npm install redis@3
- 现有客户端创建代码无需修改,v3版本会自动建立连接。
额外检查
- 确认Redis服务正在运行,且配置的
host和port正确; - 更新rate-limiter-flexible到最新版本,避免版本兼容问题:
npm update rate-limiter-flexible
内容的提问来源于stack exchange,提问作者user19926947
相关产品推荐
相关产品推荐

