Guard 的职责只有一个:
判断当前请求是否有资格继续执行。
比如登录态守卫:
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;
}
}使用:
import { Controller, Get, UseGuards } from '@nestjs/common';
@Controller('flights')
@UseGuards(AuthGuard)
export class FlightsController {
@Get()
findAll() {
return [];
}
}类比成机场安检:
请求到达
↓
Guard 安检闸机
├── 有资格 -> 继续进柜台
└── 没资格 -> 直接拦下Guard 最容易写错的地方是:
- 在 Guard 里写一堆业务逻辑
- 在 Service 里硬塞登录校验
- 把“认证”和“授权”混成一坨
更清晰的分层是:
- 认证:你是谁
- 授权:你能做什么
- 业务:即使你能做,这件事在业务上是否允许
官方安全文档也支持把 Guard 全局化,再对少数公开接口打 public 标记。这是现代 API 常见做法。