全书目录

第七篇:NestJS 完全指南 —— 国际机场总调度宇宙

第十章:Guard —— 它决定“能不能进”,不是“进来后怎么办”

1 分钟 222 字 第 190 / 962 个阅读单元

Guard 的职责只有一个:

判断当前请求是否有资格继续执行。

比如登录态守卫:

ts
import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const authHeader = request.headers.authorization;

    if (!authHeader?.startsWith('Bearer ')) {
      throw new UnauthorizedException('未登录');
    }

    return true;
  }
}

使用:

ts
import { Controller, Get, UseGuards } from '@nestjs/common';

@Controller('flights')
@UseGuards(AuthGuard)
export class FlightsController {
  @Get()
  findAll() {
    return [];
  }
}

类比成机场安检:

text
请求到达
  ↓
Guard 安检闸机
  ├── 有资格 -> 继续进柜台
  └── 没资格 -> 直接拦下

Guard 最容易写错的地方是:

  • 在 Guard 里写一堆业务逻辑
  • 在 Service 里硬塞登录校验
  • 把“认证”和“授权”混成一坨

更清晰的分层是:

  • 认证:你是谁
  • 授权:你能做什么
  • 业务:即使你能做,这件事在业务上是否允许

官方安全文档也支持把 Guard 全局化,再对少数公开接口打 public 标记。这是现代 API 常见做法。