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

NestJS使用Reflector无法获取自定义Public装饰器值,抛出TypeError

无法获取Public装饰器值,抛出TypeError问题解决

我无法获取自定义的用于公开路由的Public装饰器的值,总是抛出ERROR [ExceptionsHandler] TypeError错误。以下是我的auth.middleware.ts代码:

// auth.middleware.ts
import { Injectable, NestMiddleware, Reflector } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  constructor(private readonly reflector: Reflector) {}

  use(req: Request, res: Response, next: NextFunction) {
    const isPublic = this.reflector.get<boolean>('isPublic', req.route?.stack[0]?.method);
    console.log('isPublic:', isPublic);

    if (!isPublic) {
      // Implement your authentication logic here
      // For example, you can use JWT verification
      // and attach the user to the request: req.user = decodedUser;
    }

    next();
  }
}

问题原因

代码中req.route?.stack[0]?.method返回的是HTTP方法字符串(如GET、POST),而Nest的元数据是附加在控制器类或路由方法对象上的,并非字符串类型。用字符串作为reflector.get的目标参数,会直接触发类型错误。

解决步骤

1. 确认Public装饰器定义正确

确保你的Public装饰器是通过SetMetadata正确定义的:

// public.decorator.ts
import { SetMetadata } from '@nestjs/common';

export const Public = () => SetMetadata('isPublic', true);

2. 修改中间件获取元数据的逻辑

将获取isPublic的代码改为从路由对应的控制器类和方法对象上读取元数据:

// auth.middleware.ts(修改后)
import { Injectable, NestMiddleware, Reflector } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  constructor(private readonly reflector: Reflector) {}

  use(req: Request, res: Response, next: NextFunction) {
    // 获取路由对应的处理函数
    const handler = req.route?.stack[0]?.handle;
    // 从控制器类和处理方法上合并获取isPublic元数据
    const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [
      handler?.constructor,
      handler,
    ]);
    
    console.log('isPublic:', isPublic);

    if (!isPublic) {
      // 实现你的认证逻辑,比如JWT验证并将用户信息挂载到req上
      // req.user = decodedUser;
    }

    next();
  }
}

3. 确认装饰器正确应用

确保在需要公开的路由方法上正确使用@Public()装饰器:

// example.controller.ts
import { Controller, Get } from '@nestjs/common';
import { Public } from './public.decorator';

@Controller('example')
export class ExampleController {
  @Public()
  @Get('public')
  getPublicData() {
    return { message: '这是公开数据' };
  }

  @Get('private')
  getPrivateData() {
    return { message: '这是需要认证的私有数据' };
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:06:24