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

Fastify项目中基于API密钥有效性的条件化速率限制问题

解决方案:基于API密钥有效性的动态路由限流

你遇到的核心问题是无效API密钥的客户端共享了同一个限流计数器,因为keyGenerator对所有无效密钥都返回'false',导致一个客户端触发限流后,其他无效密钥的客户端也会被限制。通过设置global: false搭配preHandler钩子,可以实现按客户端单独计数的动态限流,具体实现如下:

步骤1:修改限流插件注册配置

关闭全局限流,仅在需要的路由上启用限流:

await fastify.register(fastifyRateLimit, {
  timeWindow: '1 minute', // 保持时间窗口配置
  global: false, // 禁用全局限流,改为路由级按需配置
});

步骤2:编写前置处理钩子(preHandler)

创建一个钩子函数,提前验证API密钥有效性,并为当前请求设置专属的限流标识和阈值:

async function rateLimitPreHandler(request) {
  const apiKey = request.headers['x-api-key'];
  let isValidApiKey = false;

  if (apiKey) {
    // 复用你的验证逻辑,注意转换为布尔值
    const validateResult = await validateToken(fastify, apiKey);
    isValidApiKey = validateResult === 'true';
  }

  // 为限流生成唯一key:
  // - 有效密钥:用密钥本身作为标识(同一密钥共享限流)
  // - 无效密钥:用客户端IP+UA作为标识(每个客户端单独计数)
  request.rateLimitKey = isValidApiKey 
    ? apiKey 
    : `${request.ip}-${request.headers['user-agent'] || 'unknown'}`;
  
  // 设置对应限流阈值
  request.rateLimitMax = isValidApiKey ? 1000 : 1;
}

步骤3:在目标路由上应用限流

在需要限流的路由中,通过config.rateLimit配置限流规则,读取preHandler中设置的参数:

// 示例:GET / 路由
fastify.get('/', {
  preHandler: rateLimitPreHandler,
  config: {
    rateLimit: {
      keyGenerator: (request) => request.rateLimitKey,
      max: (request) => request.rateLimitMax,
    },
  },
}, async (request, reply) => {
  return { hello: 'world' };
});

// 示例:POST /test 路由
fastify.post('/test', {
  preHandler: rateLimitPreHandler,
  config: {
    rateLimit: {
      keyGenerator: (request) => request.rateLimitKey,
      max: (request) => request.rateLimitMax,
    },
  },
}, async (request, reply) => {
  // 可以直接复用preHandler的验证结果,无需重复调用validateToken
  const isValid = request.rateLimitKey === request.headers['x-api-key'];
  console.log('API key valid:', isValid);
  
  return { foo: 'bar' };
});

关键逻辑说明

  1. 无效客户端单独计数:通过IP+UA作为无效密钥的限流标识,确保每个客户端的限流计数器独立,不会互相影响。
  2. 动态阈值配置:根据密钥有效性,分别设置1000次/分钟和1次/分钟的限流阈值。
  3. 避免重复验证:preHandler中提前完成密钥验证,路由处理逻辑可以直接复用结果,提升性能。

内容的提问来源于stack exchange,提问作者stefano manzi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:45:09