守卫
创建守卫
守卫有单独的责任。它们根据运行时出现的某些条件(例如权限,角色,访问控制列表等)来确定给定的请求是否由路由处理程序处理。这通常称为授权。在传统的 Express 应用程序中,通常由中间件处理授权(以及认证)。
守卫在中间件后执行
我们在user里创建一个守卫
cd src/user
nest g gu myrole
守卫要求实现函数canActivate
,给定参数context执行上下文要求返回布尔值
使用UseGuards
控制守卫
user.controller.ts
import {
Controller,
UseGuards,
} from '@nestjs/common';
import { MyroleGuard } from './myrole/myrole.guard';
@UseGuards(MyroleGuard)
@Controller()
XXXXXX
全局守卫
main.ts
import { MyroleGuard } from './user/myrole/myrole.guard';
app.useGlobalGuards(new MyroleGuard());
针对角色控制守卫
@SetMetadata
装饰器
第一个参数为key,第二个参数自定义,这里放数组格式来读权限
guard 使用 Reflector反射读取setMetaData的值去做判断,假如从url 判断有没有admin权限
myrole.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 MyroleGuard implements CanActivate {
constructor(private Reflector: Reflector) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const admin = this.Reflector.get<string[]>('myrole', context.getHandler());
const request = context.switchToHttp().getRequest<Request>();
console.log('经过了守卫', admin, request.query);
if (admin?.includes(request?.query?.myrole as string)) {
return true;
} else {
return false;
}
}
}
如果通过
通过失败
注意全局守卫,如果还是使用如下方式就会报错
main.ts
app.useGlobalGuards(new MyroleGuard());
我们需要传入Reflector,issues,即
main.ts
import { MyroleGuard } from './user/myrole/myrole.guard';
import { Reflector } from '@nestjs/core';
app.useGlobalGuards(new MyroleGuard(new Reflector()));