代码之家  ›  专栏  ›  技术社区  ›  Paolito75

用户检查器-使用实体管理器

  •  1
  • Paolito75  · 技术社区  · 6 年前

    我的网站运行的是symfony 3.4,我建立了自己的用户成员系统。 我的用户实体包含一个日期时间字段“lastlogin”,我找不到每次用户登录时更新该字段的解决方案。

    我创建了一个自定义用户检查器,然后尝试更新其中的字段:

    <?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(); 我得到:

    致命错误:调用未定义的方法 corebundle\security\userchecker::get()。

    1 回复  |  直到 6 年前
        1
  •  3
  •   V-Light    6 年前

    不知道为什么@doncallisto撤职了。这是对的。

    看一看 http://symfony.com/doc/current/components/security/authentication.html#authentication-success-and-failure-events

    所以你有几个选择。

    • SecurityEvents::INTERACTIVE_LOGIN -每次用户 填写登录表单并提交凭据。会有用的,但是你 无法获取上次登录更新 如果你有 remember_me 饼干或类似的

    • AuthenticationEvents::AUTHENTICATION_SUCCESS -触发器 每一次 (每个请求)验证成功时。这意味着你 last_login 将更新 每一次 每一个 除非用户已登录,否则请求 外面的

    所以您需要一个事件订阅服务器。看看这篇文章。 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();
        }
    }
    

    附笔。 fosUserBundle使用交互式登录和自定义事件设置实体上的最后一次登录 看: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/EventListener/LastLoginListener.php#L63