当我全局提供它时,NestJs 中的 Guard 不起作用

问题描述 投票:0回答:1

我在 NestJS 应用程序中全局使用 AuthGuard 组件来保护路由,同时允许使用公共装饰器公开某些路由。然而,守卫并没有按预期运行,因为我可以向任何路线发送请求,即使是那些没有公共装饰器的路线,也不会面临任何限制。

authGuard

import { JwtService } from '@nestjs/jwt';
import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { IS_PUBLIC_KEY } from './utils';
import { jwtConstants } from './constants';
import { Request } from 'express';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private jwtService: JwtService,
    private reflector: Reflector,
  ) {}

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

    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      request['user'] = await this.jwtService.verifyAsync(token, {
        secret: jwtConstants.secret,
      });
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}

公共装饰

import { SetMetadata } from '@nestjs/common';

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

应用程序模块

providers: [
  AppService,
  {
    provide: APP_GUARD,
    useClass: AuthGuard, 
  },
],

控制器示例

@Post()
@UseInterceptors(
  FileInterceptor('image', {
    storage: diskStorage({
      destination: './uploads/news',
      filename: fileName,
    }),
  }),
)

In the controller i didnt put Public decorator but its working

我尝试将 authguard 本身放入我想要保护的路由中,但这种方法也不起作用

nestjs nest guard
1个回答
0
投票

您需要在您的

main.ts

中将此守卫定义为全局守卫
const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new AuthGuard());

顺便说一下,你不需要在

canActivate
类的
AuthGuard
方法中抛出错误,你可以返回一个布尔值,Nest 可以处理其余的,因为你的守卫正在实现
CanActivate
接口。

© www.soinside.com 2019 - 2024. All rights reserved.