Skip to main content
Version: Next

Authentication and authorization

You might not want to expose your GraphQL API to anyone. Or you might want to keep some queries/mutations/subscriptions or fields reserved to some users.

GraphQLite offers some control over what a user can do with your API. You can restrict access to resources:

  • based on authentication using the #[Logged] attribute (restrict access to logged users)
  • based on authorization using the #[Right] attribute (restrict access to logged users with certain rights).
  • based on fine-grained authorization using the #[Security] attribute (restrict access for some given resources to some users).
GraphQLite does not have its own security mechanism. Unless you're using our Symfony Bundle or our Laravel package, it is up to you to connect this feature to your framework's security mechanism.
See Connecting GraphQLite to your framework's security module.

#[Logged] and #[Right] attributes

GraphQLite exposes two attributes (#[Logged] and #[Right]) that you can use to restrict access to a resource.

namespace App\Controller;

use TheCodingMachine\GraphQLite\Annotations\Query;
use TheCodingMachine\GraphQLite\Annotations\Logged;
use TheCodingMachine\GraphQLite\Annotations\Right;

class UserController
{
/**
* @return User[]
*/
#[Query]
#[Logged]
#[Right("CAN_VIEW_USER_LIST")]
public function users(int $limit, int $offset): array
{
// ...
}
}

In the example above, the query users will only be available if the user making the query is logged AND if he has the CAN_VIEW_USER_LIST right.

#[Logged] and #[Right] attributes can be used next to:

  • #[Query] attributes
  • #[Mutation] attributes
  • #[Field] attributes
By default, if a user tries to access an unauthorized query/mutation/subscription/field, an error is raised and the query fails.

Not throwing errors

If you do not want an error to be thrown when a user attempts to query a field/query/mutation/subscription they have no access to, you can use the #[FailWith] attribute.

The #[FailWith] attribute contains the value that will be returned for users with insufficient rights.

class UserController
{
/**
* If a user is not logged or if the user has not the right "CAN_VIEW_USER_LIST",
* the value returned will be "null".
*
* @return User[]
*/
#[Query]
#[Logged]
#[Right("CAN_VIEW_USER_LIST")]
#[FailWith(value: null)]
public function users(int $limit, int $offset): array
{
// ...
}
}

Injecting the current user as a parameter

Use the #[InjectUser] attribute to get an instance of the current user logged in.

namespace App\Controller;

use TheCodingMachine\GraphQLite\Annotations\Query;
use TheCodingMachine\GraphQLite\Annotations\InjectUser;

class ProductController
{
/**
* @return Product
*/
#[Query]
public function product(
int $id,
#[InjectUser]
User $user
): Product
{
// ...
}
}

The #[InjectUser] attribute can be used next to:

  • #[Query] attributes
  • #[Mutation] attributes
  • #[Field] attributes

The object injected as the current user depends on your framework. It is in fact the object returned by the "authentication service" configured in GraphQLite. If user is not authenticated and parameter's type is not nullable, an authorization exception is thrown, similar to #[Logged] attribute.

Hiding fields / queries / mutations / subscriptions

By default, a user analysing the GraphQL schema can see all queries/mutations/subscriptions/types available. Some will be available to him and some won't.

If you want to add an extra level of security (or if you want your schema to be kept secret to unauthorized users), you can use the #[HideIfUnauthorized] attribute. Beware of it's limitations.

class UserController
{
/**
* If a user is not logged or if the user has not the right "CAN_VIEW_USER_LIST",
* the schema will NOT contain the "users" query at all (so trying to call the
* "users" query will result in a GraphQL "query not found" error.
*
* @return User[]
*/
#[Query]
#[Logged]
#[Right("CAN_VIEW_USER_LIST")]
#[HideIfUnauthorized]
public function users(int $limit, int $offset): array
{
// ...
}
}

While this is the most secured mode, it can have drawbacks when working with development tools (you need to be logged as admin to fetch the complete schema).

The "HideIfUnauthorized" mode was the default mode in GraphQLite 3 and is optional from GraphQLite 4+.