Login / Logout
Login
Pour vérifier que nous somme bien identifié nous rajoutons dans notre entité User la condition is_granted('ROLE_USER')
à l'opération GET collection d'utilisateurs.
* collectionOperations={
* "get"={
* "security"="is_granted('ROLE_USER')",
* },
Ainsi quand on fait une requete GET /users
nous avons la réponse 401 suivante :
{
"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Full authentication is required to access this resource.",
// ...
Nous allons également déclarer une nouvelle route sur notre entité User qui nous permettra de nous identifier :
* "login"={
* "method"="POST",
* "path"="/login",
* "controller"=LoginAction::class
* },
LoginAction.php
<?php
namespace App\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class LoginAction extends AbstractController
{
public function __invoke(Request $request)
{
if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
return $this->json([
'error' => 'Invalid login request: check that the Content-Type header is "application/json".'
], Response::HTTP_BAD_REQUEST);
}
return $this->json($this->getUser());
}
}
Nous avons besoin de connaitre le nom de cette route pour l'indiquer dans notre firewall
. Pour ça nous utilisons la commande php bin/console debug:router
qui nous liste toutes les routes et nous avons le nom que nous cherchons affiché :
Dans config/packages/security.yaml
nous pouvons indiquer un nouveau firewall et la route est api_users_login_collection
.
security:
encoders:
App\Entity\User:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
json_login:
check_path: api_users_login_collection
username_path: email
password_path: password
Maintenant, nous pouvons faire un POST /api/login
{
"email": "Immanuel_Bradtke7@yahoo.com",
"password": "P@sswordS3cure"
}
et nous avons comme réponse
{
"id": 12,
"email": "Immanuel_Bradtke7@yahoo.com",
"roles": [
"ROLE_USER"
]
}
Qui nous indique que nous nous sommes bien identifiés. Dans le cas contraire (avec un mauvais mot de passe par exemple) nous avons :
{
"error": "Invalid credentials."
}
Maintenant si nous refaisons un GET /api/users
nous avons une réponse 200 qui nous liste les utilisateurs.
Avec cette configuration, lorsque nous envoyons une requête
POST /api/login
, l'authentificateurjson_login
va automatiquement se mettre en route, chercher du JSON dans la requête, le décoder, et utiliser les clés email et mot de passe qu'il contient pour nous connecter.Avec le provider
app_user_provider
cela indique au système de sécurité que notre utilisateur est dans Doctrine et qu'il doit le rechercher via la propriété email.
Logout
Nous allons créer une nouvelle route pour se déconnecter. Dans notre entité User nous la rajoutons :
* "logout"={
* "method"="POST",
* "path"="/logout",
* "controller"=LogoutAction::class,
* },
Le contenu de LogoutAction est le suivant
<?php
namespace App\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class LogoutAction extends AbstractController
{
public function __invoke()
{
throw new \Exception('should not be reached');
}
}
Maintenant, en faisant un POST /api/logout
puis à nouveau un GET /api/users/
vous verrez que vous aurez à nouveau le message Full authentication is required to access this resource.
Commentaires
Connectez-vous pour laisser un commentaire