DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for UserChecker Symfony.6.0.15
Roberto Manchado
Roberto Manchado

Posted on

UserChecker Symfony.6.0.15

sometimes we need authenticate a user on symfony with other field or property after the password verification, for example, a field or column with name verificated or expired ( in case that the column is a DateTime ).

we can use The Security Events and the flow is how follow:

Image description

We have 5 types of Events that are triggered when the user put the password in the input field and push the submit button. The events are:

  • CheckPassportEvent
  • AuthenticationTokenCreatedEvent
  • AuthenticationSuccessEvent
  • LoginSuccessEvent
  • LoginFailureEvent

The first event, CheckPassportEvent, allow see the information of User Object before the auth, and we can, in this case, throw an exception.

Even better, Symfony have a cool tool called , UserChecker, that implement the UserCheckerInterface interface and you can access to the User Object before the auth.

For example:

namespace App\Security;

use App\Entity\User as AppUser;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class UserChecker implements UserCheckerInterface
{
    public function checkPreAuth(UserInterface $user): void
    {
        if (!$user instanceof AppUser) {
            return;
        }

        if ($user->isDeleted()) {
            // the message passed to this exception is meant to be displayed to the user
            throw new CustomUserMessageAccountStatusException('Your user account no longer exists.');
        }
    }

    public function checkPostAuth(UserInterface $user): void
    {
        if (!$user instanceof AppUser) {
            return;
        }

        // user account is expired, the user may be notified
        if ($user->isExpired()) {
            throw new AccountExpiredException('...');
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The interface have two methods, checkPreAuth and checkPostAuth, and allow catch, the information of User Entity before the access token is created. A good place for put our conditions.

In this example, we can throw an exception, if the user is deleted or the user is not verified yet ( when we send a email to user for activate an user's account ) :

 if ($user->isDeleted()) {
            // the message passed to this exception is meant to be displayed to the user
            throw new CustomUserMessageAccountStatusException('Your user account no longer exists.');
    }

Enter fullscreen mode Exit fullscreen mode

and show the exception on a Twig template:

{% if error %}
<div class="alert alert-danger">
   {{ error.messageKey|trans(error.messageData, 'security') }}
</div>
{% endif %}
Enter fullscreen mode Exit fullscreen mode

Image description

@see SecurityEvents

@see How to Create and Enable Custom User Checkers

Tutorial

Top comments (0)

Join us at DEV Want to join the conversation?
Β 

It's easy! Become a DEV member to follow this post, comment, and more.