一.基本概念
1、作用?
守卫是一个使用Injectable装饰器所装饰的类,并且implements了CanActivate这个interface,守卫一般用来进行权限判断。
2、如何使用脚手架创建守卫?
3、如何创建守卫?
代码举例如下所示:
1 2 3 4 5 6 7 8 9 10
| import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { Observable } from 'rxjs';
@Injectable() export class AuthGuard extends CanActivate { canActivate(context: ExecutionContext): bool | Promise<boolean> | Observable<boolean> { const request = context.switchToHttp().getRequest(); return validateRequest(request); } }
|
也就是说,对于一个守卫guard类来说,必须使用Injectable装饰器进行装饰,必须implements接口CanActivate,必须实现canActive类方法。
4、如何使用守卫?
可以对整个controller类应用守卫,如下所示:
1 2 3 4 5 6 7 8
| import { Controller, UseGuards } from '@nestjs/common'; import { RolesGuard } form '../guard/roles.guard';
@Controller('/news') @UseGuards(RolesGuard) export class NewsController {
}
|
也可以只针对controller类中的某一个路由方法应用守卫,如下所示:
1 2 3 4 5 6 7 8 9 10 11
| import { Controller, UseGuards, Get, Query } from '@nestjs/common'; import { RolesGuard } from '../guard/roles.guard';
@Controller('/news') export class NewsController { @Get('topic') @UseGuards(RolesGuard) getHotNews(@Query() queryObj) {
} }
|
也可以配置一个全局守卫,如下所示:
1 2 3 4
| import { RolesGuard } from './guards/roles.guard';
app.useGlobalGuards(new RolesGuard());
|
配置全局守卫还有下面这种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import { Module } form '@nestjs/common'; import { APP_GUARD } form '@nestjs/core'; import { RolesGuard } from './guard/roles.guard';
@Module({ providers: [ { provide: APP_GUARD, useClass: RolesGuard, } ] })
|
注意,在使用UseGuards装饰器的时候,参数既可以是guard类也可以是guard实例。
5、守卫应用后有什么效果?
前面也提到了,守卫最终会返回布尔值,守卫在接收到了request,进入到controller路由之前被执行,如果guard返回true的话,那么路由正常执行;如果guard返回false的话,那么返回403状态码,controller中的路由方法得不到运行机会。
6、应用了全局守卫后,如果不想某些路由被守卫拦截的话该怎么做?
举例如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; import { Observable } from 'rxjs';
@Injectable() export class AuthGuard extends CanActivate { canActivate(context: ExecutionContext): bool | Promise<boolean> | Observable<boolean> { const request = context.switchToHttp().getRequest(); const whiteList = ['/login', 'index']; const path = request.path; if (whiteList.includes(path)) return true; } }
|