推荐答案
在 Nest.js 中,守卫(Guard)用于在请求到达控制器之前执行一些逻辑,例如权限验证。要创建一个守卫,可以按照以下步骤进行:
- 使用
@nestjs/common
中的Injectable
装饰器:守卫是一个带有@Injectable()
装饰器的类。 - 实现
CanActivate
接口:守卫类需要实现CanActivate
接口,并实现canActivate
方法。 - 在
canActivate
方法中编写逻辑:该方法返回一个布尔值或一个Promise<boolean>
,决定是否允许请求继续。
示例代码:
-- -------------------- ---- ------- ------ - ----------- ------------ ---------------- - ---- ----------------- ------ - ---------- - ---- ------- ------------- ------ ----- --------- ---------- ----------- - ------------ -------- ----------------- -- ------- - ---------------- - ------------------- - ----- ------- - ------------------------------------ ------ ------------------------------ - ------- ------------------------ ----- ------- - -- ----------- ------ ----- -- -- ----- - -
- 应用守卫:可以通过
@UseGuards()
装饰器将守卫应用到控制器或路由上。
-- -------------------- ---- ------- ------ - ----------- ---- --------- - ---- ----------------- ------ - --------- - ---- --------------- ------------------- --------------------- ------ ----- -------------- - ------ ---------- ------ - ------ ----- ------ ------- --- ------ - -
本题详细解读
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
,请求将被拒绝。