You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJs Guards执行顺序异常求助:AbilityGuard先于AuthGuard执行

问题分析与修复方案

核心问题:守卫执行顺序异常

按NestJS官方规则,控制器级守卫应优先于路由(方法)级守卫执行,但你遇到AbilitiesGuard先运行的情况,大概率是因为控制器上的JwtAuthenticationGuard没有被Nest正确管理,或者守卫的声明方式导致顺序错乱。另外你的AbilitiesGuard里还有个潜在的取值逻辑错误。

具体修复步骤

1. 修正JwtAuthenticationGuard的声明方式

你的JwtAuthenticationGuard缺少@Injectable()装饰器,且控制器上用new手动实例化,这会导致Nest无法按正常生命周期管理它。修改如下:

import { AuthGuard } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';

@Injectable() // 添加装饰器,让Nest可以依赖注入管理
export class JwtAuthenticationGuard extends AuthGuard('jwt') {}

然后控制器上改为使用类声明守卫,不要手动new:

@ApiTags('Tenant')
@Controller('tenant')
@UseGuards(JwtAuthenticationGuard) // 用类引用,而非手动实例化
export class TenantController {
  // ... 原有代码
}

2. 明确守卫执行顺序

如果只需要当前路由做权限校验,直接在路由上按认证在前、权限在后的顺序声明两个守卫:

@Post()
@CheckAbilities({action: UserAction.CREATE, subject: User})
@UseGuards(JwtAuthenticationGuard, AbilitiesGuard) // 顺序不能反,先完成身份认证
async create(@CurrentUser() user: User, @Body() createTenantDto: CreateTenantDto) {
  try {
    return await this._tenantService.create(user,createTenantDto);
  } catch (error) { 
    throw error;
  }
}

如果所有路由都需要JWT认证,保留控制器级的JwtAuthenticationGuard即可,此时控制器级守卫会先执行,再执行路由级的AbilitiesGuard。

3. 修复request.user的取值逻辑

JWT AuthGuard默认会把用户对象直接绑定到request.user,你当前的解构逻辑存在错误,应改为:

const request = context.switchToHttp().getRequest();
const user = request.user; // 直接取request.user,无需额外解构
console.log(user);
const ability = this.abilityFactory.defineAbility(user);

如果你的JWT策略validate方法返回的是{ user: 实体对象 }格式,才需要用const { user } = request.user;,否则直接取request.user即可。

验证执行顺序

可以在两个守卫的canActivate方法中添加日志,确认执行顺序:

// JwtAuthenticationGuard
async canActivate(context: ExecutionContext): Promise<boolean> {
  console.log('=== JWT认证守卫执行 ===');
  return super.canActivate(context);
}

// AbilitiesGuard
async canActivate(context: ExecutionContext): Promise<boolean> {
  console.log('=== 权限校验守卫执行 ===');
  // ... 原有代码
}

调用接口后,控制台应先输出JWT守卫的日志,再输出权限守卫的日志,此时request.user就能正确获取到用户信息了。


内容的提问来源于stack exchange,提问作者DavidSch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 04:40:24