守卫(guard)
守卫有一个单独的责任。它们根据运行时出现的某些条件(例如权限,角色,访问控制列表等)来确定给定的请求是否由路由处理程序处理。这通常称为授权。在传统的 Express 应用程序中,通常由中间件处理授权(以及认证)。中间件是身份验证的良好选择,因为诸如token验证或添加属性到request对象上与特定路由(及其元数据)没有强关联。
tips 守卫在每个中间件之后执行,但在任何拦截器或管道之前执行。
创建一个守卫
nest g gu [name]
新建模块guard,在guard模块下新建role守卫
Controller 使用守卫
使用UseGuards控制守卫
import { RoleGuard } from './role/role.guard'; //引入
@UseGuards(RoleGuard) //使用
全局守卫
app.useGlobalGuards(new RoleGuard())
针对角色控制守卫
SetMetadata装饰器
第一个参数为key,第二个参数自定义(里面定义我们能够访问哪些角色,比如定义了role为admin的时候,我们才能访问finaAll)
我们的例子是数组存放的权限
guard.controller.ts
guard使用Reflector反射读取setMetaData的值去做判断,例子是从url 判断有没有admin权限
role.guard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Request } from 'express';
import { Observable } from 'rxjs';
@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())
const req=context.switchToHttp().getRequest<Request>() //获取请求对象
return admin.includes(req.query.role as string)
// req.query请求参数对象,里面包含了role属性,因为访问地址是http://localhost:3000/guard?role=admin
}
}
成功情况,访问地址http://localhost:3000/guard?role=admin
失败情况,访问地址http://localhost:3000/guard?role=11