Nest.js 中如何创建守卫?

推荐答案

在 Nest.js 中,守卫(Guard)用于在请求到达控制器之前执行一些逻辑,例如权限验证。要创建一个守卫,可以按照以下步骤进行:

  1. 使用 @nestjs/common 中的 Injectable 装饰器:守卫是一个带有 @Injectable() 装饰器的类。
  2. 实现 CanActivate 接口:守卫类需要实现 CanActivate 接口,并实现 canActivate 方法。
  3. canActivate 方法中编写逻辑:该方法返回一个布尔值或一个 Promise<boolean>,决定是否允许请求继续。

示例代码:

-- -------------------- ---- -------
------ - ----------- ------------ ---------------- - ---- -----------------
------ - ---------- - ---- -------

-------------
------ ----- --------- ---------- ----------- -
  ------------
    -------- -----------------
  -- ------- - ---------------- - ------------------- -
    ----- ------- - ------------------------------------
    ------ ------------------------------
  -

  ------- ------------------------ ----- ------- -
    -- -----------
    ------ ----- -- -- -----
  -
-
  1. 应用守卫:可以通过 @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. 守卫的执行顺序

守卫的执行顺序是:

  1. 全局守卫
  2. 控制器级别的守卫
  3. 路由级别的守卫

如果任何一个守卫返回 false,请求将被拒绝。

纠错
反馈