Symfony2 FOSbundle:记录每个用户的登录日期

时间:2016-02-04 14:00:51

标签: php symfony fosuserbundle

每次用户登录Symfony2时如何存储记录?

我创建了UserLog实体,我想记录记录的id,用户的id和登录日期。

我正在使用FOS用户包进行用户管理。我看到只记录每个用户Symfony2 Login and Security的最后一次登录的问题,但是无法弄清楚如何记录每个登录日期

3 个答案:

答案 0 :(得分:0)

您需要覆盖默认的身份验证处理程序并在那里登录。

  1. 您需要创建新身份验证处理程序的服务:
  2. services.yml:

        parameters:
        fos_user_security.component.authentication.handler.login_success_handler.class: Path\To\New\Handler
    
    
    
        services:
    fos_user_security.component.authentication.handler.login_success_handler:
                 class:  %fos_user_security.component.authentication.handler.login_success_handler.class%
                 arguments:  [@router, @security.context]
                 tags:
                     - { name: 'monolog.logger', channel: 'security' }
    
    1. 创建处理程序并执行逻辑:
    2. 命名空间Application \ Sonata \ UserBundle \ Services;

      use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
      use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
      use Symfony\Component\Security\Core\SecurityContext;
      use Symfony\Component\HttpFoundation\Request;
      use Symfony\Component\HttpFoundation\RedirectResponse;
      use Symfony\Component\Routing\Router;
      
      class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
      {
      
          protected $router;
          protected $security;
      
          public function __construct(Router $router, SecurityContext $security)
          {
              $this->router = $router;
              $this->security = $security;
          }
      
          public function onAuthenticationSuccess(Request $request, TokenInterface $token)
          {
      
              if ($this->security->isGranted('ROLE_USER'))
      
              // create your new entity and add the data you need
      
              }
      
              return $response;
          }
      
      1. 在security.yml中,您需要定义新的success_handler,如下所示:

        main:
            pattern:             ^/
            context:             user
            form_login:
                provider:       fos_userbundle
                csrf_provider: form.csrf_provider
                login_path:     /login
                #use_forward:    false
                check_path:     fos_user_security_check
                success_handler: fos_user_security.component.authentication.handler.login_success_handler // the handler
                #failure_path:   null
                always_use_default_target_path: false
                default_target_path: profile
        

答案 1 :(得分:0)

您必须实施一个AuthenticationHandler来监听onAuthenticationSuccess事件。

首先,使用getter和setter在用户实体(datetime,nullable)中创建lastLogin字段。

然后,创建如下:

<?php

namespace Acme\TestBundle\Handler;

use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\DependencyInjection\ContainerAware;

class AuthenticationHandler extends ContainerAware implements AuthenticationSuccessHandlerInterface
{
    function onAuthenticationSuccess(Request $request, TokenInterface $token)
    {
        $user = $token->getUser();
        $lastLogin = new \DateTime();

        $user->setLastLogin($lastLogin);
        $this->container->get('doctrine')->getEntityManager()->flush();

        // redirect the user for example
        return new RedirectResponse($this->container->get('router')->generate('login_success'));
    }
}

将其注册为服务:

// app/config/services.yml
services:
    authentication_handler:
        class: Acme\TestBundle\Handler\AuthenticationHandler
        calls:
            - [ setContainer, [ @service_container ] ]

并将其配置为身份验证success_handler

// app/config/security.yml
# ...
form_login:
    # ...
    success_handler: authentication_handler

希望这对你有所帮助。

编辑

我的错误,谢谢@JasonRoman。

创建一个包含lastLogin属性的LoginRecord等实体,而不是date属性。

/**
 * LoginRecord.
 *
 * @ORM\Entity
 * @ORM\Table(name="user_logins")
 */
class LoginRecord
{
    // Identifier

    /** @ORM\Column(name="date", type="date") */
    protected $date;

    /**
     * @ORM\ManyToOne(targetEntity="\Acme\TestBundle\Entity\User", inversedBy="loginRecords")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
     */
    protected $user;

    public function setDate($date)
    {
        $this->date = $date;

        return $date;
    }

    public function getDate()
    {
        return $this->date;
    }

    public function setUser(User $user)
    {
        $this->user = $user;

        return $this;
    }

    public function getUser()
    {
        return $this->user;
    }

}

然后,在您的用户实体中添加一个名为$loginRecords的属性,表示与LoginRecord的{​​{1}}的一对多关联。

targetClass

而不是使用// User entity class User { // ... Your other properties /** @ORM\OneToMany(targetEntity="\Acme\TestBundle\Entity\LoginRecord", mappedBy="user", cascade={"persist", "remove"}) */ protected $loginRecords; public function __construct() { // ... $this->loginRecords = new \Doctrine\Common\Collections\ArrayCollection(); } public function addLoginRecord(LoginRecord $loginRecord) { $this->loginRecords[] = $loginRecord; $loginRecord->setUser($this); return $this; } public function removeLoginRecord(LoginRecord $loginRecord) { $this->loginRecords->removeElement($loginRecord); } public function getLoginRecords() { return $this->loginRecords; } } ,而是使用setLastLogin来记录addLoginRecord($date)中的用户登录信息:

AuthenticationHandler

答案 2 :(得分:0)

  

这是Symfony4.2的解决方案

根据Symfony documentation,必须收听security.interactive_login事件并创建LoginListener

  

代码1

app.login_listener:
    class: App\EventListener\LoginListener
    tags:
        - { name: 'kernel.event_listener', event: 'security.interactive_login' }
  

代码2

// src/EventListener/LoginListener.php

namespace App\EventListener;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

class LoginListener
{
    private $em;

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

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        // Get the User entity.
        $user = $event->getAuthenticationToken()->getUser();

        // Update your field here.
        $user->setLastLogin(new \DateTime());

        // Persist the data to database.
        $this->em->persist($user);
        $this->em->flush();
    }
}
  

必须调整此示例以满足定制需求。

例如LoginListener的信用额转到Rihards Steinbergs