守卫的主要作用是鉴权,即判断用户有没有权限访问接口中的特定服务
- 创建一个守卫 nest g gu role
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; import { Observable } from 'rxjs'; // 注意Reflector是一个类,需要先在构造器的参数列表中声明 import { Reflector } from '@nestjs/core'; import { Request } from 'express'; @Injectable() export class RoleGuard implements CanActivate { constructor(private Reflector:Reflector){} canActivate( context: ExecutionContext, ): boolean | Promise<boolean> | Observable<boolean> { console.log('通过了守卫') // 返回true代表放行,false代表拒绝 return true }
- 在login.controller.ts里注册
import { RoleGuard } from '../role/role.guard'; import { SetMetadata } from '@nestjs/common'; @Controller('login') export class LoginController { constructor(private readonly loginService: LoginService) {} @Get() // 在这里注册 @UseGuards(RoleGuard) findAll() { return this.loginService.findAll(); } }
此时访问localhost:3000/login控制台就会打印'通过了守卫'
鉴权
- 在上文守卫的基础上使用@SetMetadata()装饰器自定义一个路由元数据,我们一会儿通过反射得到它
- 修改role.guard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; import { Observable } from 'rxjs'; import { Reflector } from '@nestjs/core'; import { Request } from 'express'; @Injectable() export class RoleGuard implements CanActivate { constructor(private Reflector:Reflector){} canActivate( context: ExecutionContext, ): boolean | Promise<boolean> | Observable<boolean> { // 获取刚才定义的路由元数据 const admin = this.Reflector.get<string[]>('role',context.getHandler()) console.log('通过了守卫',admin) // 获取前端请求信息 const req = context.switchToHttp().getRequest<Request>() // 检查请求信息中是否包含特定字段,如有则放行 if(admin.includes(req.query.role as string)){ return true }else{ return false } } }
context:context实际上是一个ExecutionContext类,官方文档中有相应说明