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

NestJS自定义Guard中Reflector注入失败问题求助

问题描述

在Nest应用中尝试使用Reflector的getAllAndOverride方法读取路由装饰器时遇到以下问题:

  • 自定义Guard继承Passport的AuthGuard时,Reflector对象存在但并非Reflector实例
  • 仅实现CanActivate接口时,Reflector为undefined
    两种情况调用getAllAndOverride均报错

创建了基础测试项目test-guard,仅做了以下修改:

  1. 新增自定义装饰器public.decorator.ts:
import { SetMetadata } from '@nestjs/common';

export const PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(PUBLIC_KEY, true);
  1. 新增自定义Guard test-guard.ts:
import { Reflector } from '@nestjs/core';
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { PUBLIC_KEY } from './public.decorator';

Injectable()
export class TestGuard implements CanActivate {
    constructor(private readonly reflector: Reflector) {}
    
      canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
        console.log(typeof(this.reflector));
        console.log(this.reflector instanceof Reflector);

        const isPublic = this.reflector.getAllAndOverride(PUBLIC_KEY, [
          context.getHandler(),
          context.getClass(),
        ]);
    
        if (isPublic) return true;
    
        return false;
      }
}
  1. 在AppModule中通过Provider注册全局守卫:
{
  provide: APP_GUARD,
  useClass: TestGuard,
},

测试时出现报错,TestGuard中的this.reflector为undefined,报错信息如下:

[12:00:55] File change detected. Starting incremental compilation...

[12:00:55] Found 0 errors. Watching for file changes.

[Nest] 7844  - 14-01-2024 12:00:55     LOG [NestFactory] Starting Nest application...
[Nest] 7844  - 14-01-2024 12:00:55     LOG [InstanceLoader] AppModule dependencies initialized +8ms
[Nest] 7844  - 14-01-2024 12:00:55     LOG [RoutesResolver] AppController {/}: +12ms
[Nest] 7844  - 14-01-2024 12:00:55     LOG [RouterExplorer] Mapped {/, GET} route +2ms
[Nest] 7844  - 14-01-2024 12:00:55     LOG [NestApplication] Nest application successfully started +2ms
undefined
false
[Nest] 7844  - 14-01-2024 12:00:57   ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'getAllAndOverride')
TypeError: Cannot read properties of undefined (reading 'getAllAndOverride')
    at TestGuard.canActivate (C:\wamp64\www\test-guard\src\test-guard.ts:14:41)
    at GuardsConsumer.tryActivate (C:\wamp64\www\test-guard\node_modules\@nestjs\core\guards\guards-consumer.js:15:34)
    at canActivateFn (C:\wamp64\www\test-guard\node_modules\@nestjs\core\router\router-execution-context.js:134:59)
    at C:\wamp64\www\test-guard\node_modules\@nestjs\core\router\router-execution-context.js:42:37
    at C:\wamp64\www\test-guard\node_modules\@nestjs\core\router\router-proxy.js:9:23
    at Layer.handle [as handle_request] (C:\wamp64\www\test-guard\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\wamp64\www\test-guard\node_modules\express\lib\router\route.js:144:13)
    at Route.dispatch (C:\wamp64\www\test-guard\node_modules\express\lib\router\route.js:114:3)
    at Layer.handle [as handle_request] (C:\wamp64\www\test-guard\node_modules\express\lib\router\layer.js:95:5)
    at C:\wamp64\www\test-guard\node_modules\express\lib\router\index.js:284:15

改用main.ts手动实例化守卫时可正常工作:

app.useGlobalGuards(new TestGuard(new Reflector()),);
问题原因与解决方案

核心问题

TestGuard类上的Injectable()调用缺少**@**装饰器符号,导致Nest无法识别该类为可注入的依赖类,因此不会自动注入Reflector实例。

修复步骤

  1. 修正TestGuard的装饰器,添加@符号:
import { Reflector } from '@nestjs/core';
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { PUBLIC_KEY } from './public.decorator';

// 添加@符号
@Injectable()
export class TestGuard implements CanActivate {
    constructor(private readonly reflector: Reflector) {}
    
      canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
        console.log(typeof(this.reflector));
        console.log(this.reflector instanceof Reflector);

        const isPublic = this.reflector.getAllAndOverride(PUBLIC_KEY, [
          context.getHandler(),
          context.getClass(),
        ]);
    
        if (isPublic) return true;
    
        return false;
      }
}
  1. 保留AppModule中注册全局守卫的配置,无需手动实例化:
{
  provide: APP_GUARD,
  useClass: TestGuard,
},

验证效果

修复后,Nest会自动为TestGuard注入Reflector实例,getAllAndOverride方法可正常调用,全局守卫功能正常工作。后续注入其他服务时,依赖注入机制也能正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:54:53