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

Laravel Lighthouse GraphQL中如何让@guard在@validator之前执行?

解决Lighthouse中鉴权先于验证执行的问题

方案一:调整@Guard指令的执行优先级

Lighthouse的指令执行顺序由$priority属性控制,数值越大越先执行。默认情况下@validator的优先级高于@guard,我们可以自定义一个高优先级的Guard指令来覆盖默认行为:

  1. 创建自定义Guard指令:
<?php

namespace App\GraphQL\Directives;

use Nuwave\Lighthouse\Auth\Directives\GuardDirective;

class PrioritizedGuardDirective extends GuardDirective
{
    // 设置更高优先级,确保比@validator先执行(默认@validator优先级为100)
    public static int $priority = 200;
}
  1. 在lighthouse.php配置文件中注册该自定义指令:
'directives' => [
    'guard' => App\GraphQL\Directives\PrioritizedGuardDirective::class,
],

后续使用@guard指令时,会优先于@validator完成鉴权,再执行验证逻辑。

方案二:将验证逻辑移至Resolver中手动执行

放弃使用@validator指令,改为在Resolver内先完成鉴权,再手动触发验证规则:

  1. 定义输入验证规则(可放在独立的Request类中):
<?php

namespace App\GraphQL\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreatePostRequest extends FormRequest
{
    public function rules()
    {
        return [
            'title' => 'required|string|max:255',
            'user_id' => 'required|exists:users,id',
        ];
    }
}
  1. 在Resolver中先鉴权,再执行验证:
<?php

namespace App\GraphQL\Resolvers;

use App\GraphQL\Requests\CreatePostRequest;
use App\Models\Post;
use Illuminate\Support\Facades\Auth;
use GraphQL\Error\Error;

class CreatePostResolver
{
    public function __invoke($root, array $args)
    {
        // 先执行鉴权逻辑
        if (!Auth::guard('api')->check()) {
            throw new Error('Unauthorized');
        }

        // 手动触发验证
        $request = CreatePostRequest::createFromGlobals();
        $request->merge($args['input']);
        $validatedData = $request->validate();

        // 执行业务逻辑
        return Post::create($validatedData);
    }
}
  1. 在GraphQL Schema中移除@validator指令,指定自定义Resolver:
type Mutation {
    createPost(input: CreatePostInput!): Post! @guard(with: ["api"]) @resolver(class: "App\\GraphQL\\Resolvers\\CreatePostResolver")
}

方案三:通过Pipeline全局调整执行顺序

修改Lighthouse的字段处理Pipeline,将鉴权环节移至验证之前:

  1. 创建自定义Pipeline工厂类:
<?php

namespace App\GraphQL\Pipelines;

use Nuwave\Lighthouse\Execution\PipelineFactory;
use Nuwave\Lighthouse\Auth\Pipeline\Authorize;
use Nuwave\Lighthouse\Validation\Pipeline\Validate;

class PrioritizedPipelineFactory extends PipelineFactory
{
    protected function steps(): array
    {
        $steps = parent::steps();
        
        // 将鉴权步骤移到验证步骤之前
        $authorizePos = array_search(Authorize::class, $steps);
        $validatePos = array_search(Validate::class, $steps);
        
        if ($authorizePos !== false && $validatePos !== false && $authorizePos > $validatePos) {
            unset($steps[$authorizePos]);
            array_splice($steps, $validatePos, 0, Authorize::class);
        }
        
        return $steps;
    }
}
  1. 在lighthouse.php配置中替换默认的Pipeline工厂:
'execution' => [
    'pipeline_factory' => App\GraphQL\Pipelines\PrioritizedPipelineFactory::class,
],

该方案会全局调整所有字段的执行顺序,确保鉴权优先于验证完成。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:57:24