一、关于 NestJS 中的守卫
- https://docs.nestjs.cn/8/guards
- 守卫是一个使用 @Injectable() 装饰器的类。守卫应该实现 CanActivate 接口
- 守卫有一个单独的责任。它们根据运行时出现的某些条件(例如权限,角色,访问控制列表等)来确定给定的请求是否由路由处理程序处理。 这通常称为授权。在传统的 Express 应用程序中,通常由中间件处理授权。中间件是身份验证的良好选择。到目前为止,访问限制逻辑大多在中间件内。这样很好,因为诸如 token 验证或将 request 对象附加属性与特定路由没有强关联
- 中间件不知道调用 next() 函数后会执行哪个处理程序。另一方面,警卫可以访问 ExecutionContext 实例,因此确切地知道接下来要执行什么。它们的设计与异常过滤器、管道和拦截器非常相似,目的是让您在请求/响应周期的正确位置插入处理逻辑,并以声明的方式进行插入。这有助于保持代码的简洁和声明性
- 说白了:在 Nextjs 中如果我们想做权限判断的话可以在守卫中完成,也可以在中间件中完成
二、NestJS 中创建守卫、以及控制器中单独配置守卫
```typescript // 1.创建守卫 nest g guard guard/auth
// 2.守卫创建完成后生成如下代码: import { CanActivate, ExecutionContext, Injectable } from ‘@nestjs/common’; import { Observable } from ‘rxjs’;
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise
// 3.使用守卫 import { Controller, Get, UseGuards } from ‘@nestjs/common’; import { AuthGuard } from ‘src/guard/auth.guard’;
@Controller(‘admin/mall1’) @UseGuards(AuthGuard) // 配置守卫,整个控制器都要进行权限判断 export class Mall1Controller { @Get() index() { return ‘我是admin模块里面mall1的页面’; }
@Get('add')
@UseGuards(AuthGuard) // 在方法上使用守卫,只在该方法上进行权限判断
addIndex() {
return '我是admin模块里面mall1的页面';
}
}
<a name="cLgbR"></a>
### 三、NestJS 中全局配置守卫
```typescript
// src/main.ts
import { AuthGuard } from './guard/auth.guard'; // 引入守卫
app.useGlobalGuards(new AuthGuard()); // 全局配置守卫
四、在 NestJS 的守卫中获取 Cookie 和 Session
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const req = context.switchToHttp().getRequest();
if (req.path === '/admin/login') {
return true;
} else {
// 判断是否有用户信息
const userinfo = context.switchToHttp().getRequest().session.username;
if (userinfo) {
return true;
}
return false;
}
}
}