Symfony 5 security.interactive_login事件未调用 [英] Symfony 5 security.interactive_login event not called

查看:60
本文介绍了Symfony 5 security.interactive_login事件未调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 security.interactive_login 事件更新用户的上次登录字段.

I want to use the security.interactive_login event to update my User's last login field.

该事件已成功注册:

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探查器中的不称为侦听器上.

But it lands on Not called listeners in the Symfony profiler.

这是事件订阅者:

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的默认生成类.

The LoginAuthenticator class is Symfony's default generated one.

为什么没有调用 交互式登录 事件?

Why the interactive login event is not called?

推荐答案

在使用新的(ish)身份验证管理器时,将INTERACTIVE_LOGIN事件替换为LoginSuccessEvent.

When using the new(ish) authentication manager, the INTERACTIVE_LOGIN event is replaced with the 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);
    }

我不确定这是否已被明确记录.像许多升级折旧一样,代码非常混乱.我试图跟踪发生的情况,并很快(再次)迷失在安全林中.

I'm not sure if this is explicitly documented yet. Like many upgrade depreciations, the code is very confusing. I tried to trace through what was happening and quickly got lost (once again) in the Security forest.

此处谈论活动.

我通过创建一个新的5.1项目,运行make:auth并为这两个事件添加了一个侦听器来发现此行为.但是我忘了在安全配置中添加enable_authenticator_manager:true.

I discovered this behavior by creating a fresh 5.1 project, running make:auth and adding a listener for both events. But I forgot to add enable_authenticator_manager: true to the security config.

因此触发了INTERACTIVE_LOGIN事件.启用新管理员后,将触发LoginSuccessEvent.请注意,新事件具有一些其他帮助器方法,例如getUser.使代码更简洁一点.

So the INTERACTIVE_LOGIN event was fired. After enabling the new manager, the LoginSuccessEvent was fired. Notice that the new event has some additional helper methods such as getUser. Makes the code a tiny bit cleaner.

离题,但我提醒您不要在侦听器内部刷新实体管理器.根据其他情况,可能会有些不可预测.可能考虑仅获取数据库连接并执行sql更新.

Off-topic but I would caution against flushing the entity manager inside of a listener. It can be a bit unpredictable depending on what else is going on. Might consider just getting the database connection and executing a sql update.

这篇关于Symfony 5 security.interactive_login事件未调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆