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).
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
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).