NestJS 守卫

117 阅读1分钟

守卫是一个用 @Injectable() 装饰器注释的类,它实现了 CanActivate 接口。

守卫有一个 单一职责。 它们根据运行时存在的某些条件(如权限、角色、ACL 等)确定给定请求是否将由路由处理程序处理。 这通常称为 authorization。 在传统的 Express 应用中,授权(及其表亲 authentication,通常与之合作)通常由 middleware 处理。 中间件是身份验证的不错选择,因为诸如令牌验证和将属性附加到 request 对象之类的事情与特定路由上下文(及其元数据)没有紧密联系。

role.guard.ts

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { Reflector } from '@nestjs/core'
import type { Request } from 'express'

@Injectable()
export class RoleGuard implements CanActivate {
  constructor(private reflector:Reflector){}
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest<Request>()
    const roles = this.reflector.get<string[]>('role',context.getHandler())
    return roles.includes(request.query.role as string)
  }
}

使用

import { RoleGuard } from './role/role.guard'
@UseGuards(RoleGuard)

可以针对整个controller 或者 单一接口

全局守卫

app.useGlobalGuards(new RolesGuard())
import { Controller, Get, Post, Body, Patch, Param, Delete,UseGuards,SetMetadata } from '@nestjs/common';
import { GuardService } from './guard.service';
import { CreateGuardDto } from './dto/create-guard.dto';
import { UpdateGuardDto } from './dto/update-guard.dto';
import { RoleGuard } from './role/role.guard'

@Controller('guard')
@UseGuards(RoleGuard)
export class GuardController {
  constructor(private readonly guardService: GuardService) {}

  @Post()
  create(@Body() createGuardDto: CreateGuardDto) {
    return this.guardService.create(createGuardDto);
  }

  @Get('g')
  @SetMetadata('role',['admin'])
  findAll() {
    return this.guardService.findAll();
  }
}

运行

有权限 image.png

没权限 image.png