Symfony 5 security.interactive_login 事件未调用
Symfony 5 security.interactive_login event not called
我想使用 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 }
LoginAuthenticatorclass是Symfony默认生成的。
为什么交互式登录事件没有被调用?
使用新的(ish)身份验证管理器时,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);
}
我不确定这是否已明确记录在案。像许多升级弃用一样,代码非常混乱。我试图追踪正在发生的事情,但很快在安全森林中迷路了(又一次)。
事件被谈论here。
我通过创建一个新的 5.1 项目 运行 make:auth
并为这两个事件添加一个侦听器来发现此行为。但是我忘了添加 enable_authenticator_manager: true 到安全配置中。
所以 INTERACTIVE_LOGIN
事件被触发了。启用新管理器后,LoginSuccessEvent
被解雇。请注意,新事件有一些额外的辅助方法,例如 getUser。使代码更简洁。
Off-topic 但我会警告不要在侦听器中刷新实体管理器。根据发生的其他情况,它可能有点不可预测。可能会考虑只获取数据库连接并执行 SQL 更新。
我想使用 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 }
LoginAuthenticatorclass是Symfony默认生成的。
为什么交互式登录事件没有被调用?
使用新的(ish)身份验证管理器时,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);
}
我不确定这是否已明确记录在案。像许多升级弃用一样,代码非常混乱。我试图追踪正在发生的事情,但很快在安全森林中迷路了(又一次)。
事件被谈论here。
我通过创建一个新的 5.1 项目 运行 make:auth
并为这两个事件添加一个侦听器来发现此行为。但是我忘了添加 enable_authenticator_manager: true 到安全配置中。
所以 INTERACTIVE_LOGIN
事件被触发了。启用新管理器后,LoginSuccessEvent
被解雇。请注意,新事件有一些额外的辅助方法,例如 getUser。使代码更简洁。
Off-topic 但我会警告不要在侦听器中刷新实体管理器。根据发生的其他情况,它可能有点不可预测。可能会考虑只获取数据库连接并执行 SQL 更新。