所以我在 Nest.js graphql 应用程序中配置了以下内容,这似乎有效;
@Module({
imports: [
ThrottlerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
ttl: config.get('THROTTLE_TTL'),
limit: config.get('THROTTLE_LIMIT'),
}),
}),
],
providers: [
{
provide: APP_GUARD,
useClass: ThrottlerGuard,
},
],
})
export class AppModule {}
但是当我尝试对本地服务器进行负载测试时,丢弃的请求都会引发以下错误
[Nest] 3177 - 2022-09-18T16:25:36.188Z ERROR [ExceptionsHandler] Cannot read property 'ip' of undefined
TypeError: Cannot read property 'ip' of undefined
为什么请求处理程序无法捕获 IP 地址?是 b/c 通过一个本地主机到另一个本地主机吗?
如文档所示,需要扩展
ThrottlerGuard
才能使 getRequestResponse
方法返回正确的值,以便可以正确引用 ip
和 headers
对象。
@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 };
}
}
同时处理 Graphql 和 http 请求
import { ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import {ThrottlerGuard} from '@nestjs/throttler';
@Injectable()
export class CustomThrottlerGuard extends ThrottlerGuard {
getRequestResponse(context: ExecutionContext) {
if (context.getType() === 'http') {
const ctx = context.switchToHttp();
return {req: ctx.getRequest(), res: ctx.getResponse() };
}
const gqlCtx = GqlExecutionContext.create(context);
const ctx = gqlCtx.getContext();
return {req: ctx.req, res: ctx.res };
}
}