推荐答案
Nest.js 守卫(Guards)是一种用于控制请求是否应该被路由处理程序处理的机制。守卫的主要职责是根据特定的条件(如权限、角色、身份验证等)来决定是否允许请求继续执行。守卫在请求到达控制器之前执行,因此非常适合用于实现权限验证、身份验证等逻辑。
守卫通过实现 CanActivate 接口来工作。该接口要求实现一个 canActivate 方法,该方法返回一个布尔值或一个 Promise<boolean> 或 Observable<boolean>。如果返回 true,请求将继续执行;如果返回 false,请求将被拒绝。
本题详细解读
1. 守卫的基本结构
守卫是一个带有 @Injectable() 装饰器的类,并且实现了 CanActivate 接口。CanActivate 接口要求实现 canActivate 方法,该方法接收两个参数:context 和 next。
// 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 true; // 或 false
}
}2. 守卫的执行时机
守卫在请求到达控制器之前执行。这意味着你可以在守卫中执行一些前置逻辑,比如检查用户的身份验证状态、权限等。如果守卫返回 false,请求将不会继续执行,并且会返回一个 403 Forbidden 响应。
3. 守卫的应用场景
- 身份验证:检查用户是否已登录。
- 权限控制:检查用户是否有权限访问某个资源。
- 请求验证:检查请求是否符合某些条件(如请求头、请求体等)。
4. 守卫的使用方式
守卫可以通过多种方式应用到路由上:
- 全局守卫:通过
app.useGlobalGuards方法应用到所有路由。 - 控制器守卫:通过
@UseGuards装饰器应用到整个控制器。 - 方法守卫:通过
@UseGuards装饰器应用到单个路由处理程序。
// www.javascriptcn.com code example
// 全局守卫
app.useGlobalGuards(new AuthGuard());
// 控制器守卫
@Controller('cats')
@UseGuards(AuthGuard)
export class CatsController {}
// 方法守卫
@Controller('cats')
export class CatsController {
@Get()
@UseGuards(AuthGuard)
findAll() {
return 'This action returns all cats';
}
}5. 守卫的执行顺序
守卫的执行顺序与它们在 @UseGuards 装饰器中的顺序一致。如果有多个守卫,它们会按照顺序依次执行,直到某个守卫返回 false 或所有守卫都返回 true。
6. 守卫的异步支持
守卫的 canActivate 方法可以返回 Promise<boolean> 或 Observable<boolean>,这意味着你可以在守卫中执行异步操作,比如从数据库中查询用户权限。
@Injectable()
export class AuthGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const user = await this.authService.validateUser(request);
return !!user;
}
}7. 守卫的异常处理
如果守卫返回 false,Nest.js 会抛出一个 ForbiddenException,并返回 403 Forbidden 响应。你可以通过自定义异常处理来改变这种行为。
// www.javascriptcn.com code example
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
if (!request.user) {
throw new UnauthorizedException();
}
return true;
}
}通过以上内容,你应该对 Nest.js 守卫的工作原理有了深入的理解。守卫是 Nest.js 中非常强大的工具,能够帮助你轻松实现复杂的权限控制和请求验证逻辑。