NestJS 守卫指南
NestJS 守卫决定请求是否被处理。学习 JWT 守卫、基于角色的访问控制、@UseGuards 和全局守卫注册。
1. JWT 认证守卫
@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private jwtService: JwtService, private reflector: Reflector) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [
context.getHandler(), context.getClass(),
]);
if (isPublic) return true;
const request = context.switchToHttp().getRequest();
const [type, token] = request.headers['authorization']?.split(' ') ?? [];
if (type !== 'Bearer' || !token) throw new UnauthorizedException('缺少 token');
try {
request['user'] = await this.jwtService.verifyAsync(token, { secret: this.configService.get('JWT_SECRET') });
return true;
} catch {
throw new UnauthorizedException('token 无效');
}
}
}
2. 基于角色的守卫
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
export const Public = () => SetMetadata('isPublic', true);
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<string[]>('roles', [
context.getHandler(), context.getClass(),
]);
if (!requiredRoles?.length) return true;
const { user } = context.switchToHttp().getRequest();
return requiredRoles.some(role => user.roles?.includes(role));
}
}
@Controller('admin')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
export class AdminController { ... }
3. 全局守卫注册
@Module({
providers: [
{ provide: APP_GUARD, useClass: JwtAuthGuard },
{ provide: APP_GUARD, useClass: RolesGuard },
],
})
export class AppModule {}
// 所有路由默认受保护,使用 @Public() 取消保护