Symfony 5 событие security.interactive_login не вызвано - PullRequest
1 голос
/ 05 августа 2020

Я хочу использовать событие security.interactive_login для обновления поля последнего входа в систему моего пользователя.

Событие успешно зарегистрировано:

php bin/console debug:event-dispatcher security.interactive_login

Registered Listeners for "security.interactive_login" Event
===========================================================

 ------- ------------------------------------------------------------------------ ----------
  Order   Callable                                                                 Priority
 ------- ------------------------------------------------------------------------ ----------
  #1      App\EventSubscriber\UserLocaleSubscriber::onSecurityInteractiveLogin()   0
 ------- ------------------------------------------------------------------------ ----------

Но оно происходит Не вызывается слушатели в профилировщике Symfony.

Это подписчик на событие:

class UserLocaleSubscriber implements EventSubscriberInterface
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        /** @var User $user */
        $user = $event->getAuthenticationToken()->getUser();

        $user->setLastLoginAt(new DateTime());
        $this->em->persist($user);
        $this->em->flush();
    }

    public static function getSubscribedEvents()
    {
        return [
            SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
        ];
    }
}

И есть мой security.yaml файл:

security:
    enable_authenticator_manager: true
    encoders:
        App\Entity\User:
            algorithm: auto

    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js|fonts)/
            security: false
        main:
            lazy: true
            provider: app_user_provider
            guard:
                authenticators:
                    - App\Security\LoginAuthenticator
            logout:
                path: app_logout
                target: app_login               # where to redirect after logout
            remember_me:
                secret:   '%kernel.secret%'
                lifetime: 604800                # 1 week in seconds
                path:     /
    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/(?!login), roles: ROLE_ADMIN }

Класс LoginAuthenticator - это класс Symfony, созданный по умолчанию.

Почему событие интерактивный вход не выполняется звонил?

1 Ответ

1 голос
/ 05 августа 2020

При использовании нового диспетчера аутентификации (i sh) событие INTERACTIVE_LOGIN заменяется на событие LoginSuccessEvent.

# my subscriber
    public static function getSubscribedEvents()
    {
        return [
            //SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
            LoginSuccessEvent::class => 'onLoginSuccess'
        ];
    }
    public function onLoginSuccess(LoginSuccessEvent $event)
    {
        $user = $event->getUser();
        $user->setCount($user->getCount() + 1);
        $this->em->flush();
        //dd($user);
    }

Я не уверен, что это явно задокументировано. Как и многие другие устаревшие версии, код очень запутанный. Я попытался отследить происходящее и быстро (снова) заблудился в лесу безопасности.

События обсуждаются здесь .

Я обнаружил это поведение по создание проекта fre sh 5.1, запуск make: auth и добавление слушателя для обоих событий. Но я забыл добавить enable_authenticator_manager: true в конфигурацию безопасности.

Итак, событие INTERACTIVE_LOGIN было запущено. После включения нового менеджера событие LoginSuccessEvent было запущено. Обратите внимание, что у нового события есть некоторые дополнительные вспомогательные методы, такие как getUser. Делает код немного чище.

Off-topi c но я бы предостерегал от очистки диспетчера сущностей внутри слушателя. Это может быть немного непредсказуемо в зависимости от того, что еще происходит. Вы можете просто установить соединение с базой данных и выполнить обновление sql.

...