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

NestJS GraphQL自定义验证器中如何获取上下文用户信息

在GraphQL自定义验证器中获取当前用户的方案

要在Class Validator的自定义验证器里拿到当前用户,核心是通过ValidationArguments获取Nest的执行上下文,再转换为GraphQL上下文提取用户信息,以下是两种可行实现方式:

方式一:通过验证器参数传递上下文

1. 实现自定义验证器

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
import { GqlExecutionContext, ExecutionContext } from '@nestjs/graphql';

@ValidatorConstraint({ name: 'userPermissionValidator', async: false })
export class UserPermissionValidator implements ValidatorConstraintInterface {
  validate(value: any, args: ValidationArguments) {
    // 从验证参数中获取传入的执行上下文
    const ctx = args.constraints[0] as ExecutionContext;
    // 转换为GraphQL专属上下文
    const gqlCtx = GqlExecutionContext.create(ctx);
    // 提取用户(逻辑和你自定义的CurrentUser装饰器一致)
    const user = gqlCtx.getContext().req.user;

    // 示例验证逻辑:仅拥有指定权限的用户可通过
    if (!user || !user.permissions.includes('edit_resource')) {
      return false;
    }
    return true;
  }

  defaultMessage(args: ValidationArguments) {
    return '你没有权限执行此操作';
  }
}

2. 在GraphQL输入DTO中使用验证器

在输入类型里通过@Validate装饰器,将ExecutionContext作为参数传入验证器:

import { InputType, Field } from '@nestjs/graphql';
import { Validate } from 'class-validator';
import { UserPermissionValidator } from './user-permission.validator';
import { ExecutionContext } from '@nestjs/common';

@InputType()
export class UpdateResourceInput {
  @Field()
  resourceId: string;

  @Field()
  @Validate(UserPermissionValidator, [ExecutionContext])
  newName: string;
}

方式二:依赖注入获取上下文(无需传参)

如果不想每次使用验证器都传递上下文,可以通过依赖注入ExecutionHost来自动获取:

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
import { GqlExecutionContext } from '@nestjs/graphql';
import { ExecutionHost, Injectable } from '@nestjs/common';

@ValidatorConstraint({ name: 'userPermissionValidator', async: false })
@Injectable()
export class UserPermissionValidator implements ValidatorConstraintInterface {
  constructor(private readonly executionHost: ExecutionHost) {}

  validate(value: any, args: ValidationArguments) {
    // 通过注入的ExecutionHost获取上下文并转换
    const gqlCtx = GqlExecutionContext.create(this.executionHost);
    const user = gqlCtx.getContext().req.user;

    // 验证逻辑同上
    if (!user || !user.permissions.includes('edit_resource')) {
      return false;
    }
    return true;
  }

  defaultMessage(args: ValidationArguments) {
    return '你没有权限执行此操作';
  }
}

注意:这种方式需要将验证器添加到对应模块的providers数组中,确保Nest可以完成依赖注入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:43:17