27 avr. 2024 | Connexion

Blog

Symfony : empêcher un compte "inactif" de se connecter

Symfony : empêcher un compte "inactif" de se connecter

Développement web Sécurité
Symfony PHP Twig

il y a 2 ans citizenz7 2 commentaires 3176 lectures

Dans notre entité User on a notamment cette ligne :

/**
* @ORM\Column(type="boolean")
*/
private $isActive = true;

(Ci-dessus, isActive = true comme ça à chaque inscription le compte est actif par défaut)

Et les setters et getters :

public function getIsActive(): ?bool
{
    return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
    $this->isActive = $isActive;
    return $this;
}

Question : comment refuser la connexion à un utilisateur dont le compte est inactif, c'est à dire qu'il a probalement été désactivé par l'admin pour certaines raisons (spam, non respect des bonnes pratiques sur le site, non paiement, etc.)

C'est relativement simple et ca se passe en deux étapes.

On va créer deux fonctions qui vont "vérifier" la connection : avant et après.

Pour cela, rendez-vous dans /src/Security et créez un nouveau fichier UserChecker.php qui va :
- vérifier l'instance (c'est bien un $user ?) -> L’opérateur instanceof est utilisé en PHP pour savoir si un objet est une instance instanciée d’une classe.
- vérifier si le $user en question est bien actif
- puis s'occuper de ce qui va se passer après que le user est cliqué sur le bouton "Se connecter"

L'objectif n'est pas de refuser la page de connexion au user mais bel et bien de refuser la connexion au compte. Le user pourra donc entrer ses identifiants mais se verra refuser la connexion avec un message d'erreur.

/src/Security/UserChecker.php

<?php
namespace App\Security;

use App\Entity\User;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class UserChecker implements UserCheckerInterface
{
    public function checkPreAuth(UserInterface $user)
    {
        if (!$user instanceof User) {
            return;
        }
        if (!$user->getIsActive()) {
            throw new CustomUserMessageAuthenticationException(
                'Inactive account cannot log in!'
            );
        }
    }
    public function checkPostAuth(UserInterface $user)
    {
        $this->checkPreAuth($user);
    }
}

La dernière chose à faire est de dire à Symfony qu'on veut interdire cette connexion.

Ca va se passer dans le fichier /config/packages/security.yaml, dans la section "firewalls" où on va pouvoir mettre la ligne suivante :

user_checker: App\Security\UserChecker

Pour la partie firewall complète, on aura donc :

firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: app_user_provider
            custom_authenticator: App\Security\UserAuthenticator
            logout:
                path: app_logout
                # where to redirect after logout
                # target: app_any_route
            user_checker: App\Security\UserChecker

Ainsi, à chaque connexion, le UserChecker va entrer en action et vérifier si le user peut ou non se connecter (isActive = true ou false).

2 commentaires


Aude, le 17-03-2024 à 21:06:13

Super, j'ai galéré 3 heures et je tombe sur votre tuto!

Caroline, le 20-04-2024 à 09:07:37

Merci beaucoup! Super efficace!

Nb d'articles actifs : 46 | Nb de commentaires : 32 | Nb de catégories : 8 | Nb de tags : 32 | Nb total de lectures : 189 622
2024 citizenz.info • Some rights reserved GPLv3 • Version 3.3.4

Ah, mais des tanches pareilles, on devrait les mettre sous verre, hein ! (Arthur, Kaamelott, Livre I, Basidiomycètes)