如何让express-rate-limit在tRPC中正常生效?
解决express-rate-limit与tRPC配合使用的问题
你的问题出在express-rate-limit是回调风格的Express中间件,而tRPC中间件基于Promise/async-await,直接调用会导致tRPC不等待限流逻辑完成就执行后续流程,所以限流没生效。
正确实现方式
将Express风格的rateLimit中间件包装成Promise,让tRPC等待其执行完成:
const test = t.middleware(async ({ next, ctx: { req, res } }) => { // 把Express中间件转为Promise,适配tRPC的异步逻辑 await new Promise((resolve, reject) => { rateLimit({ windowMs: 60 * 60 * 1000, // 1小时 max: 5, message: '该IP创建账号次数过多,请1小时后重试', standardHeaders: true, // 返回RateLimit-*标准响应头 legacyHeaders: false, // 禁用X-RateLimit-*旧版响应头 // 自定义限流触发后的处理逻辑,确保终止请求并返回正确响应 handler: (req, res) => { res.status(429).send('该IP创建账号次数过多,请1小时后重试'); reject(new Error('Too many requests')); } })(req, res, (err) => { if (err) reject(err); else resolve(); }); }); // 限流校验通过后,继续执行tRPC后续流程 return next(); });
关键注意点
- Promise包装:必须将Express中间件的回调逻辑转为Promise,保证tRPC等待限流校验完成后再继续
- 限流触发处理:通过
handler自定义限流后的响应,避免tRPC继续执行未被允许的逻辑 - 上下文校验:确保ctx中正确传入了Express的
req和res对象(这一步你已经实现,无需修改)
内容的提问来源于stack exchange,提问作者IvonaK
相关产品推荐
相关产品推荐

