我有一个带有REST模块和GraphQL模块的GraphQL应用程序。两者都被导入到一个App.module.ts中。我使用Nest的节流器护罩来保护整个应用程序。众所周知,ThrottlerGuard,所以我创建了一个GqlThrottlerGuard并在GraphQL模块上导入了它,同时在REST模块上导入了原始的ThrottlerGuard。
因此,我的graphQL模块如下所示:
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: true
}),
ThrottlerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
ttl: config.get('security.throttle.ttl'),
limit: config.get('security.throttle.limit'),
}),
}),
],
providers: [
{
provide: APP_GUARD,
useClass: GqlThrottlerGuard,
},
],
})
export class GraphModule { }剩下的模块如下:
@Module({
imports: [
ThrottlerModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
ttl: config.get('security.throttle.ttl'),
limit: config.get('security.throttle.limit'),
}),
}),
],
controllers: [RestController],
providers: [
{
provide: APP_GUARD,
useClass: ThrottlerGuard,
},
],
})
export class RestModule implements NestModule {}最后,两个模块都导入到App,而App是我实际运行的模块:
@Module({
imports: [
RestModule,
GraphModule,
],
})
export class AppModule { }由于某种原因,在这里上看到的错误仍然发生在GraphModule上,即使普通的ThrottlerGuard只在RestModule上导入。它应该像这样工作吗?我该怎么解决呢?
发布于 2022-08-16 12:39:39
APP_GUARD是一个全局绑定,它适用于所有路由。您应该建立一个一致的保护机制,根据ExecutionContext#getType方法返回适当的请求响应,该方法将返回http或graphql
@Injectable()
export class CustomThrottlerGuard extends ThrottlerGuard {
getRequestResponse(context: ExecutionContext) {
const reqType = context.getType<ContextType | 'graphql'>()
if (reqType === 'graphql') {
const gqlCtx = GqlExecutionContext.create(context);
const ctx = gqlCtx.getContext();
return { req: ctx.req, res: ctx.res };
} else if (reqType === 'http') {
return {
req: context.switchToHttp().getRequest(),
res: context.switchToHttp().getResponse()
}
} else {
// handle rpc and ws if you have them, otherwise ignore and make previous `else if` just an `else`
}
}https://stackoverflow.com/questions/73373437
复制相似问题