Before deploying lighthouse to a production server, I check security (https://www.howtographql.com/advanced/4-security/). So I decided to check query depth and query complexity.
In the lighthouse documentation, they mention config/lighthouse.php
.
/* |------------------------------------------------- ----------------------- | Security |------------------------------------------------- ----------------------- | | Control Lighthouse to handle security-related query verification. | Detailed reading: https://webonyx.github.io/graphql-php/security/ | */ 'security' => [ 'max_query_complexity' => \GraphQL\Validator\Rules\QueryComplexity::DISABLED, 'max_query_depth' => \GraphQL\Validator\Rules\QueryDepth::DISABLED, 'disable_introspection' => \GraphQL\Validator\Rules\DisableIntrospection::DISABLED, ],
And it is recommended to read https://webonyx.github.io/graphql-php/security/.
In this link they give some examples:
use GraphQL\GraphQL; use GraphQL\Validator\Rules\QueryComplexity; use GraphQL\Validator\DocumentValidator; $rule = new QueryComplexity($maxQueryComplexity = 100); DocumentValidator::addRule($rule); GraphQL::executeQuery(/*...*/);
use GraphQL\GraphQL; use GraphQL\Validator\Rules\QueryDepth; use GraphQL\Validator\DocumentValidator; $rule = new QueryDepth($maxDepth = 10); DocumentValidator::addRule($rule); GraphQL::executeQuery(/*...*/);
But how to apply these in lighthouse?
First, I wrote this code into ExampleQuery.php(php artisan lighthouse:query ExampleQuery)
.
final class ExampleQuery { public function __invoke(_, array $args) { $rule = new QueryComplexity(2); DocumentValidator::addRule($rule); $rule2 = new QueryDepth(2); DocumentValidator::addRule($rule2); return [ ... ]; } }
But this won't catch any problems.
I think lighthouse is started in vendor/nuwave/.../GraphQLController.php
so I cannot execute GraphQL::executeQuery(/*...*/ );
@complexity
directive also does not work, @complexity(resolver: "App\\Security\\ComplexityAnalyzer@userPosts")
will not be called userPosts function.
class ComplexityAnalyzer { public function userPosts(int $childrenComplexity, array $args): int // not called { $postComplexity = $args['includeFullText'] ? 3 : 2; \Log::Debug($postComplexity); // not called return $childrenComplexity * $postComplexity; } }
What did I miss? Please help me sleep well.
It's already implemented, you just need to set the value.
Complexity score calculation can be modified for each field using the@complexitydirective.