
本文介绍如何在 laravel lighthouse 中正确启用并配置 graphql 查询深度(query depth)和查询复杂度(query complexity)限制,防止恶意嵌套或爆炸式查询攻击,确保生产环境安全。
本文介绍如何在 laravel lighthouse 中正确启用并配置 graphql 查询深度(query depth)和查询复杂度(query complexity)限制,防止恶意嵌套或爆炸式查询攻击,确保生产环境安全。
Laravel Lighthouse 内置了基于 webonyx/graphql-php 的安全验证机制,无需手动调用 DocumentValidator::addRule() 或修改控制器源码——这些逻辑已在 Lighthouse 的请求生命周期中自动集成。你只需在 config/lighthouse.php 的 security 配置项中启用对应限制即可生效。
✅ 正确配置方式
打开 config/lighthouse.php,将 security 数组修改为:
'security' => [
'max_query_complexity' => 100, // 允许的最大查询复杂度分值(建议根据业务调整)
'max_query_depth' => 10, // 允许的最大嵌套层级(如 user { posts { author { profile } } } 深度为 4)
'disable_introspection' => env('LIGHTHOUSE_DISABLE_INTROSPECTION', false),
],⚠️ 注意:值设为
null、0或GraphQLValidatorRulesQueryComplexity::DISABLED均表示禁用;必须设置为正整数(如100)才会启用校验。配置后请运行php artisan config:clear确保生效。
✅ 自定义字段复杂度:@complexity 指令
Lighthouse 支持通过 @complexity 指令为特定字段指定动态复杂度权重,替代全局统一计分。例如:
type Query {
users: [User!]! @complexity(resolver: "App\Security\ComplexityAnalyzer@userList")
}对应的解析器类需实现方法(注意命名空间与方法名严格匹配):
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
<?php
namespace AppSecurity;
use GraphQLTypeDefinitionResolveInfo;
class ComplexityAnalyzer
{
public function userList(int $childrenComplexity, array $args): int
{
// 基础分 + 子字段分 × 权重
$base = 1;
$multiplier = $args['withPosts'] ?? false ? 5 : 2;
return $base + $childrenComplexity * $multiplier;
}
}? 常见失败原因排查:
- 方法未被调用?检查
resolver参数中的类路径是否正确(含命名空间转义\),且方法为public;- 类未被自动加载?运行
composer dump-autoload;- 指令拼写错误?确认是
@complexity(非@complex或@cost);- Schema 缓存未更新?执行
php artisan lighthouse:clear-cache。
? 验证是否生效
发起一个超限查询进行测试(如深度为 15 的嵌套):
query DeepQuery {
users {
id
posts {
id
author {
id
posts {
id
author { id posts { id } } # …继续嵌套至超限
}
}
}
}
}若配置正确,Lighthouse 将立即返回错误响应:
{
"errors": [{
"message": "Query has depth of 15, which exceeds max depth of 10",
"extensions": { "category": "validation" }
}]
}? 最佳实践建议
-
生产环境必启:
max_query_depth(推荐 7–12)和max_query_complexity(根据典型查询压测后设定,如 50–300); -
敏感字段加权:对关联大量数据的字段(如
posts,comments)使用@complexity提高其权重; -
配合速率限制:结合
lighthouse-rate-limit或 Laravel Sanctum 限流,形成多层防护; -
定期审计 Schema:使用 GraphiQL Playground 的 introspection 功能检查是否意外暴露敏感字段(可通过
'disable_introspection' => true关闭)。
通过以上配置,你无需侵入核心代码,即可在 Lighthouse 中稳健启用 GraphQL 安全防护,真正实现“开箱即安”。现在,安心入睡吧 ?

















