Nest核心组件 - 守卫 Guards

7/9/2023 NodejsNestjs

# 2.7 守卫(Guards)

守卫在 NestJS 中用于保护路由,实现对请求的预处理和拦截。它可以用于验证身份、权限检查、日志记录等操作。

# 2.7.1 创建一个守卫

让我们来创建一个简单的守卫。在 src 目录下创建一个新的文件 roles.guard.ts,并编写以下代码:

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return user.roles.includes('admin');
  }
}
1
2
3
4
5
6
7
8
9
10
11

在上面的代码中,我们创建了一个实现了 CanActivate 接口的守卫类 RolesGuard。CanActivate 接口要求守卫类实现 canActivate 方法,该方法将在路由被调用之前被调用。

在 canActivate 方法中,我们可以访问 ExecutionContext 对象,并从中获取请求对象 request。在这个例子中,我们假设请求对象中有一个 user 属性,表示当前用户。我们检查用户的角色是否包含 'admin',如果是,则返回 true 表示允许访问路由,否则返回 false 表示拒绝访问路由。

# 2.7.1 使用守卫

现在我们已经创建了一个简单的守卫 RolesGuard,接下来我们需要在控制器中使用它。

要使用守卫,我们可以通过 @UseGuards() 装饰器将其应用于控制器中的特定路由或全局路由。在这里我们将它应用于一个特定的控制器路由示例。

打开 cats.controller.ts 文件,并将 RolesGuard 应用于 create 方法:

import { Controller, Get, Post, Body, UsePipes, UseGuards } from '@nestjs/common';
import { CatsService } from './cats.service';
import { CreateCatDto } from './dto/create-cat.dto';
import { ValidationPipe } from '../validation.pipe';
import { RolesGuard } from '../roles.guard';

@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Post()
  @UsePipes(ValidationPipe)
  @UseGuards(RolesGuard)
  create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto.name);
  }

  @Get()
  findAll(): string[] {
    return this.catsService.findAll();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

在上面的代码中,我们在 create 方法上使用了 @UseGuards(RolesGuard) 装饰器,将 RolesGuard 应用于 create 方法。这样,当请求到达 create 方法时,会首先调用 RolesGuard 进行权限检查。

当我们发送 POST 请求到 /cats 路径时,create 方法会被调用,而在调用之前,RolesGuard 会先检查当前用户的角色是否包含 'admin',如果包含,则允许访问路由,否则拒绝访问路由。

编辑时间: 7/9/2023, 10:00:00 AM