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

NestJS GraphQL ThrottlerGuard报错:Cannot read properties of undefined (reading 'ip')

NestJS + GraphQL 限流时"Cannot read properties of undefined (reading 'ip')"问题修复

问题背景

使用NestJS、GraphQL和@nestjs/throttler开发API实现请求限流,自定义了GqlThrottlerGuard适配GraphQL场景,但发起查询时控制台抛出错误:

Cannot read properties of undefined (reading 'ip')

尽管报错,限流功能仍正常工作——连续3次请求后会正确触发"Too Many Requests"响应。已尝试以下操作但问题未解决:

  • 验证限流规则有效性
  • 按照官方文档实现自定义守卫
  • 配置trust proxy
  • 多种方式从上下文提取请求对象
  • 检查ctx.req属性是否存在
  • 重写getTracker方法

问题原因

核心原因是ThrottlerGuard的默认逻辑中,部分代码路径未正确适配GraphQL上下文结构。自定义守卫虽已提取req对象用于限流计数,但ThrottlerGuard内部的IP获取逻辑仍在尝试从原始HTTP上下文而非GraphQL上下文中读取请求对象,导致读取ip时出现undefined。

解决方案

方案1:重写getTracker方法直接获取IP

在自定义GqlThrottlerGuard中,同时重写getRequestResponse和getTracker方法,确保IP从GraphQL上下文的请求对象中获取:

import { ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { ThrottlerGuard } from '@nestjs/throttler';

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
  getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gqlCtx.getContext();
    return { req: ctx.req, res: ctx.res };
  }

  protected getTracker(context: ExecutionContext): string {
    const { req } = this.getRequestResponse(context);
    // 根据部署环境调整IP获取逻辑,比如处理反向代理场景
    return req.ip || req.ips[0] || 'unknown';
  }
}

方案2:确保GraphQL上下文传递完整HTTP对象

检查GraphQL模块配置,确保上下文正确传递req和res:

GraphQLModule.forRoot({
  // 其他配置项
  context: ({ req, res }) => ({ req, res }),
}),

方案3:重写handleRequest跳过父类错误逻辑(临时方案)

若上述方案无效,可重写handleRequest方法,绕过父类中触发错误的IP校验步骤(不推荐长期使用):

import { ThrottlerException } from '@nestjs/throttler';

// ... 其他代码

protected async handleRequest(
  context: ExecutionContext,
  limit: number,
  ttl: number,
): Promise<boolean> {
  const { req } = this.getRequestResponse(context);
  const tracker = this.getTracker(context);
  const key = this.generateKey(req, tracker);

  const { totalHits } = await this.storageService.increment(key, ttl);

  if (totalHits > limit) {
    throw new ThrottlerException();
  }

  return true;
}

验证步骤

  1. 重启NestJS服务
  2. 发起GraphQL查询,确认控制台不再抛出"Cannot read properties of undefined (reading 'ip')"错误
  3. 连续发起超过限流阈值的请求,验证"Too Many Requests"响应正常触发

内容的提问来源于stack exchange,提问作者Andres Eduardo Rosas Alpiri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:33:15