Menu

Déconnecter automatiquement un utilisateur banni sur un projet Symfony 4

Les prérequis


  • Une entité User (Avec ou sans FOSUserBundle)
  • Un système d'authentification fonctionnel pour les tests


Création de l'EventListener


Tout d'abord nous allons créer notre Class qui sera appelée et traitée sur chaque page avant le traitement du controller.

Si le dossier EventListener n'existe pas sur votre projet, créez-le puis ajoutez-y le fichier suivant.


src/EventListener/CheckNeedDisconnectListener.php :

<?php


namespace App\EventListener;


use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;

//Votre entitié User
use App\Entity\User;


class CheckNeedDisconnectListener
{
    private $tokenStorage;
    private $router;
    private $session;


    public function __construct(TokenStorageInterface $t, RouterInterface $r, SessionInterface $session)
    {
        $this->tokenStorage = $t;
        $this->router = $r;
        $this->session = $session;
    }




    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();


        /*
         * $controller passed can be either a class or a Closure.
         * This is not usual in Symfony but it may happen.
         * If it is a class, it comes in array format
         */
        if (!is_array($controller)) {
            return;
        }
        
        $token = $this->tokenStorage->getToken();
        if(!empty($token)){
            $user = $token->getUser();
            //Vérification si l'utilisateur est connecté, si il ne l'est pas alors $user ne sera pas un objet User
            if($user instanceof User){
                if($user->getBanned()){
                    // Redirection vers ma route de déconnexion
                    $redirectUrl= $this->router->generate('security_logout');
                    $event->setController(function() use ($redirectUrl) {
                        return new RedirectResponse($redirectUrl);
                    });
                }
            }
        }
    }
}


Ajout de l'évènement dans les services de Symfony


Maintenant que notre évènement est prêt, nous allons l'ajouter au KernelController qui s'occupera de jouer l'évènement sur chaque page visitée.


config/services.yaml :

parameters:
    //...
    event_listener_class: App\EventListener\CheckNeedDisconnectListener


services:
    //...
    app.event_listener:
        class: '%event_listener_class%'
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }


Phase de test


Tout est maintenant prêt, il ne vous manque plus qu'à vider le cache de votre navigateur (CTRL + F5) puis votre cache Symfony avec la commande suivante depuis la racine de votre projet :


php bin/console cache:clear


Connectez vous sur le compte d'un utilisateur, baladez vous sur votre site puis depuis votre base de donnée bannissez votre propre compte.

Une redirection vers la page de déconnexion se fera automatiquement quand vous rechargerez la page et ainsi, un utilisateur banni ne pourra plus se permettre de se balader sur le site.



Catégorie :
Symfony 4
Vues :
389