Php Symfony2 FOSbundle:记录每个用户的登录日期
如何在用户每次登录Symfony2时存储记录 我创建了UserLog实体,我想在其中记录记录的id、用户id和登录日期Php Symfony2 FOSbundle:记录每个用户的登录日期,php,symfony,fosuserbundle,Php,Symfony,Fosuserbundle,如何在用户每次登录Symfony2时存储记录 我创建了UserLog实体,我想在其中记录记录的id、用户id和登录日期 我使用FOS用户包进行用户管理。我看到了只记录每个用户最后一次登录的问题,但不知道如何记录每个登录日期,您需要覆盖默认的身份验证处理程序并在那里进行登录 您需要为新的身份验证处理程序创建服务: services.yml: parameters: fos_user_security.component.authentication.handler.login_su
我使用FOS用户包进行用户管理。我看到了只记录每个用户最后一次登录的问题,但不知道如何记录每个登录日期,您需要覆盖默认的身份验证处理程序并在那里进行登录 您需要为新的身份验证处理程序创建服务: 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' }
创建处理程序并执行以下逻辑:
名称空间应用程序\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;
}
在security.yml中,您需要定义新的success_处理程序,如下所示:
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
您必须实现一个AuthenticationHandler,用于侦听onAuthenticationSuccess事件
首先,使用getter和setter在用户实体datetime中创建lastLogin字段,可以为null
然后,创建如下内容:
<?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'));
}
}
并将其配置为身份验证成功\u处理程序:
希望这对你有帮助
编辑
我错了,谢谢@JasonRoman
创建包含日期属性的实体(如LoginRecord),而不是lastLogin属性
/**
* 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的一对多关联,即targetClass
并且,不要使用setLastLogin,而是使用addLoginRecord$date在AuthenticationHandler中记录用户登录:
下面是Symfony4.2的解决方案
根据需要,必须侦听security.interactive\u登录事件并创建LoginListener
代码1
代码2
必须调整此示例以满足定制需求
例如LoginListener进入您发布的问题中选择的答案包含您所需的一切。你尝试了什么,出了什么问题?谢谢你的解决方案。我完全按照您写的那样做了,但出现了以下错误:service security.firewall.map.context.main依赖于不存在的service fos\u user\u security.component.authentication.handler.login\u success\u处理程序。你认为会有什么问题?可能会有几个问题。您使用的是哪个Symfony版本?Symfony版本2.7.3只记录用户的最后一次登录-他希望它记录用户登录的每个日期。@chalasr我已经尝试了您的解决方案。我没有记录上次登录,而是尝试记录每次登录:$user=$token->getUser$登录\日期=新建\日期时间$用户日志=新用户日志$用户日志->设置用户$user$用户日志->设置登录日期$login\u日期$这个->容器->获取“条令”->getEntityManager->刷新;返回新的重定向响应$this->container->get'router'->generate'profile',array'user'=>$user->getUsername;它不起作用。我的意思是我已正确登录并重定向,但数据未被记录。请参阅我的示例。用户实体中的$loginRecords和addLoginRecord中的setUser$this中肯定缺少cascade={persist}。也不要忘记构造函数。
// app/config/security.yml
# ...
form_login:
# ...
success_handler: authentication_handler
/**
* 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;
}
}
// 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;
}
}
function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$user = $token->getUser();
$lastLogin = new \DateTime();
$record = new LoginRecord();
$record->setDate($lastLogin);
$user->addLoginRecord($record);
$this->container->get('doctrine')->getEntityManager()->flush();
// redirect the user for example
return new RedirectResponse($this->container->get('router')->generate('login_success'));
}
app.login_listener:
class: App\EventListener\LoginListener
tags:
- { name: 'kernel.event_listener', event: 'security.interactive_login' }
// 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();
}
}