为端点应用 JWT Guard,但在它具有请求参数时不应用它

Apply JWT Guard for an endpoint but do not apply it when it has a request parameter

在为控制器中的端点应用@UseGuards(JwtAuthGuard)规则时,是否可以使用if条件?

@UseGuards(JwtAuthGuard)
@Get("/foo/:bar?")
async get(@Param() param: RequestParamDto)

有一个端点 /foo 在调用它时应该需要 JWT 授权令牌(它使用上面的代码),但是当我们在请求参数中传递一些东西时,例如/foo/bar应该关闭一个守卫

在控制器级别应用 Guards 时,我没有看到应用 if-else 条件的方法。

您可以在守卫中应用 if-else 条件。虽然不是在控制器级别,但您可以按照以下步骤实现所需的条件:

首先,定义一个新的装饰器,代码如下:

import { SetMetadata } from '@nestjs/common';
export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);

使用此代码,您将定义一个名为 @Public() 的新装饰器。 link IS_PUBLIC_KEY 的值 true 又会 linked 给装饰器。它存在的目的是让守卫能够识别你希望哪些路线被所有人访问。

下一步是将装饰器添加到所需的路由:

@UseGuards(JwtAuthGuard)
@Get("/foo/:bar")
@Public()
async get(@Param() param: RequestParamDto)

最后,在 JwtAuthGuard class 你应该有以下代码:

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}

在canActivate 函数中的代码中,您现在使用NestJs 的反射器属性 来获取添加到自定义装饰器的常量IS_PUBLIC_KEY。因此,守卫将能够告诉您何时希望路线 public 供所有人访问。

如果您想了解有关此问题的更多信息,请参阅官方文档here