推荐答案
在 Nest.js 中,守卫(Guard)用于在请求到达控制器之前执行一些逻辑,例如权限验证。要创建一个守卫,可以按照以下步骤进行:
- 使用
@nestjs/common中的Injectable装饰器:守卫是一个带有@Injectable()装饰器的类。 - 实现
CanActivate接口:守卫类需要实现CanActivate接口,并实现canActivate方法。 - 在
canActivate方法中编写逻辑:该方法返回一个布尔值或一个Promise<boolean>,决定是否允许请求继续。
示例代码:
// www.javascriptcn.com code example
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return this.validateRequest(request);
}
private validateRequest(request: any): boolean {
// 在这里编写你的验证逻辑
return true; // 或者 false
}
}- 应用守卫:可以通过
@UseGuards()装饰器将守卫应用到控制器或路由上。
// www.javascriptcn.com code example
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from './auth.guard';
@Controller('cats')
@UseGuards(AuthGuard)
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}本题详细解读
1. 守卫的作用
守卫的主要作用是决定是否允许请求继续执行。它通常用于权限验证、角色检查等场景。守卫在中间件之后执行,但在拦截器和管道之前执行。
2. CanActivate 接口
CanActivate 接口是守卫的核心部分,它要求实现 canActivate 方法。该方法接收一个 ExecutionContext 对象,提供了当前请求的上下文信息。
3. ExecutionContext 对象
ExecutionContext 提供了访问请求和响应对象的能力。通过 context.switchToHttp().getRequest() 可以获取当前的 HTTP 请求对象。
4. 守卫的应用方式
守卫可以通过以下方式应用:
- 全局守卫:在模块级别使用
app.useGlobalGuards(new AuthGuard())来应用全局守卫。 - 控制器级别:使用
@UseGuards(AuthGuard)装饰器将守卫应用到整个控制器。 - 路由级别:使用
@UseGuards(AuthGuard)装饰器将守卫应用到特定的路由。
5. 异步守卫
如果守卫的逻辑是异步的,canActivate 方法可以返回一个 Promise<boolean> 或 Observable<boolean>,Nest.js 会等待异步操作完成后再决定是否继续请求。
6. 守卫的执行顺序
守卫的执行顺序是:
- 全局守卫
- 控制器级别的守卫
- 路由级别的守卫
如果任何一个守卫返回 false,请求将被拒绝。