UserChecker - 使用实体管理器
UserChecker - Use entity manager
我的网站是运行 Symfony 3.4,我做了自己的用户会员系统。
我的用户实体包含一个日期时间字段 'lastLogin',我找不到在用户每次登录时更新它的解决方案。
我创建了一个自定义 UserChecker,然后尝试更新其中的字段:
<?php
namespace CoreBundle\Security;
use CoreBundle\Entity\User as AppUser;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
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 AppUser) {
return;
}
if ( $user->getDeleted() || !$user->getEnabled() )
{
throw new AuthenticationException();
}
else
{
// BELOW IS WHAT I TRY, BUT FAIL.
$entityManager = $this->get('doctrine')->getManager();
$user->setLastLogin(new \DateTime());
$entityManager->persist($user);
$entityManager->flush();
}
}
public function checkPostAuth(UserInterface $user)
{
if (!$user instanceof AppUser) {
return;
}
}
}
但是没用。也许我不能在这个文件中使用学说实体管理器?
如果我使用 $this->get('doctrine')->getManager();
我得到:
Fatal Error: Call to undefined method
CoreBundle\Security\UserChecker::get()
不知道为什么@doncallisto 删除了他的post。这是(恕我直言)正确的事情。
所以你有几个选择。
SecurityEvents::INTERACTIVE_LOGIN
- 每次用户触发
填写登录表单并提交凭据。会工作,但你
如果您有 remember_me
cookie 或类似
,将不会获得 last_login 更新
AuthenticationEvents::AUTHENTICATION_SUCCESS
- 每次触发
(每个请求)身份验证成功时。这意味着您的 last_login
将在 每个 请求上 每次 更新,除非用户登录 out
所以你需要一个 EventSubscriber。看看这篇文章。 https://thisdata.com/blog/subscribing-to-symfonys-security-events/
也许您需要一个简化版本。
public static function getSubscribedEvents()
{
return array(
// AuthenticationEvents::AUTHENTICATION_FAILURE => 'onAuthenticationFailure', // no need for this at that moment
SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin', // this ist what you want
);
}
然后是 onSecurityInteractiveLogin
方法本身。
public function onSecurityInteractiveLogin( InteractiveLoginEvent $event )
{
$user = $this->tokenStorage->getToken()->getUser();
if( $user instanceof User )
{
$user->setLastLogin( new \DateTime() );
$this->entityManager->flush();
}
}
P.S。
FosUserBundle 使用 interactive_login 和自定义事件在实体上设置 last_login
看看:https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/EventListener/LastLoginListener.php#L63
朋友,你可以使用它通过构造函数注入 entityManager
use Doctrine\ORM\EntityManagerInterface;
public function __construct(EntityManagerInterface $userManager){
$this->userManager = $userManager;
}
并在 checkPreAuth 中调用它
public function checkPreAuth(UserInterface $user){
if (!$user instanceof AppUser) {
return;
}
if ( $user->getDeleted() || !$user->getEnabled() ){
throw new AuthenticationException();
}else{
// BELOW IS WHAT I TRY, BUT FAIL.
$user->setLastLogin(new \DateTime());
$this->userManager->persist($user);
$this->userManager->flush();
}
}
我的网站是运行 Symfony 3.4,我做了自己的用户会员系统。 我的用户实体包含一个日期时间字段 'lastLogin',我找不到在用户每次登录时更新它的解决方案。
我创建了一个自定义 UserChecker,然后尝试更新其中的字段:
<?php
namespace CoreBundle\Security;
use CoreBundle\Entity\User as AppUser;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
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 AppUser) {
return;
}
if ( $user->getDeleted() || !$user->getEnabled() )
{
throw new AuthenticationException();
}
else
{
// BELOW IS WHAT I TRY, BUT FAIL.
$entityManager = $this->get('doctrine')->getManager();
$user->setLastLogin(new \DateTime());
$entityManager->persist($user);
$entityManager->flush();
}
}
public function checkPostAuth(UserInterface $user)
{
if (!$user instanceof AppUser) {
return;
}
}
}
但是没用。也许我不能在这个文件中使用学说实体管理器?
如果我使用 $this->get('doctrine')->getManager();
我得到:
Fatal Error: Call to undefined method CoreBundle\Security\UserChecker::get()
不知道为什么@doncallisto 删除了他的post。这是(恕我直言)正确的事情。
所以你有几个选择。
SecurityEvents::INTERACTIVE_LOGIN
- 每次用户触发 填写登录表单并提交凭据。会工作,但你 如果您有remember_me
cookie 或类似 ,将不会获得 last_login 更新
AuthenticationEvents::AUTHENTICATION_SUCCESS
- 每次触发 (每个请求)身份验证成功时。这意味着您的last_login
将在 每个 请求上 每次 更新,除非用户登录 out
所以你需要一个 EventSubscriber。看看这篇文章。 https://thisdata.com/blog/subscribing-to-symfonys-security-events/
也许您需要一个简化版本。
public static function getSubscribedEvents()
{
return array(
// AuthenticationEvents::AUTHENTICATION_FAILURE => 'onAuthenticationFailure', // no need for this at that moment
SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin', // this ist what you want
);
}
然后是 onSecurityInteractiveLogin
方法本身。
public function onSecurityInteractiveLogin( InteractiveLoginEvent $event )
{
$user = $this->tokenStorage->getToken()->getUser();
if( $user instanceof User )
{
$user->setLastLogin( new \DateTime() );
$this->entityManager->flush();
}
}
P.S。 FosUserBundle 使用 interactive_login 和自定义事件在实体上设置 last_login 看看:https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/EventListener/LastLoginListener.php#L63
朋友,你可以使用它通过构造函数注入 entityManager
use Doctrine\ORM\EntityManagerInterface;
public function __construct(EntityManagerInterface $userManager){
$this->userManager = $userManager;
}
并在 checkPreAuth 中调用它
public function checkPreAuth(UserInterface $user){
if (!$user instanceof AppUser) {
return;
}
if ( $user->getDeleted() || !$user->getEnabled() ){
throw new AuthenticationException();
}else{
// BELOW IS WHAT I TRY, BUT FAIL.
$user->setLastLogin(new \DateTime());
$this->userManager->persist($user);
$this->userManager->flush();
}
}