You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Strapi自定义路由中express-rate-limit中间件未生效如何解决?

问题分析与解决方案

你的限流中间件未生效有两个核心原因:

  1. 执行顺序完全错误:你先调用了await next(),这会直接把请求传递到后续路由处理逻辑,等请求处理完成后才创建限流实例——相当于请求已经处理完了才做限流检查,完全起不到限制作用。
  2. 中间件类型不兼容:express-rate-limit是为Express框架设计的中间件,而Strapi基于Koa框架,两者的中间件模型不同,直接实例化无法适配Koa的上下文。

方案一:改用Koa生态的限流中间件(推荐)

使用koa-ratelimit(Koa官方生态的限流工具),适配性更好:

1. 依赖安装

npm install koa-ratelimit ioredis --save

(ioredis用于生产环境的持久化存储,开发环境可省略,改用内存存储)

2. 修正中间件代码

const RateLimit = require('koa-ratelimit');
const Redis = require('ioredis');

module.exports = () => {
  // 生产环境用Redis存储限流数据,避免重启服务后数据丢失
  const redisStore = new Redis({
    host: 'localhost', // 你的Redis地址
    port: 6379
  });

  return RateLimit({
    driver: 'redis',
    store: redisStore,
    duration: 60 * 1000, // 1分钟时间窗口
    max: 3, // 每个IP最多3次请求
    errorMessage: 'too many requests',
    id: (ctx) => ctx.ip, // 以请求IP作为限流标识
    // 可选:添加限流响应头
    headers: {
      remaining: 'X-RateLimit-Remaining',
      reset: 'X-RateLimit-Reset',
      total: 'X-RateLimit-Total'
    }
  });
};

如果是开发环境,可简化为内存存储:

const RateLimit = require('koa-ratelimit');

module.exports = () => {
  return RateLimit({
    driver: 'memory',
    duration: 60 * 1000,
    max: 3,
    errorMessage: 'too many requests',
    id: (ctx) => ctx.ip
  });
};

方案二:适配express-rate-limit到Koa环境

如果坚持使用express-rate-limit,需要将其包装为Koa兼容的中间件:

1. 依赖安装

npm install koa-express-middleware --save

2. 修正中间件代码

const rateLimit = require("express-rate-limit");
const wrap = require('koa-express-middleware');

module.exports = () => {
  // 先创建Express限流中间件实例
  const limiter = rateLimit({
    windowMs: 60 * 1000,
    max: 3,
    message: "too many requests",
  });

  // 包装为Koa中间件,并在请求处理前执行限流检查
  return async (ctx, next) => {
    await wrap(limiter)(ctx, next);
  };
};

也可以手动适配(无需额外依赖):

const rateLimit = require("express-rate-limit");

module.exports = () => {
  const limiter = rateLimit({
    windowMs: 60 * 1000,
    max: 3,
    message: "too many requests",
  });

  return async (ctx, next) => {
    return new Promise((resolve, reject) => {
      // 将Koa上下文转换为Express兼容的req/res格式
      limiter(ctx.req, ctx.res, (err) => {
        if (err) reject(err);
        else resolve(next());
      });
    });
  };
};

最后确认

你的路由配置中中间件顺序是正确的(先验权再限流),修正中间件后重新启动Strapi,即可触发1分钟内超过3次请求时返回429错误及对应提示。

内容的提问来源于stack exchange,提问作者Mohsin Tariq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:27:57