基于this问题
我已经在一段时间不活动后实现了用户的自动注销(如上面的问题)。这工作正常,但我需要为此事件创建一个日志条目。
问题是当logout触发时,我在我的日志文件中获得多条记录而不是1条记录。我想我需要听一些其他请求,而不是onKernelRequest
。任何想法如何做到这一点?我的代码如下:
<?php
namespace AppBundle\EventListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
class RequestListener{
protected $session;
protected $securityToken;
protected $router;
protected $logger;
protected $maxIdleTime;
public function __construct(Session $session, TokenStorage $securityToken, RouterInterface $router, $logger, $maxIdleTime)
{
$this->session = $session;
$this->securityToken = $securityToken;
$this->router = $router;
$this->logger = $logger;
$this->maxIdleTime = $maxIdleTime;
}
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST != $event->getRequestType()) {
return;
}
if ($this->maxIdleTime > 0) {
$lapse = time() - $this->session->getMetadataBag()->getCreated();
if ($lapse > $this->maxIdleTime) {
$username = $this->securityToken->getToken()->getUser();
if ($username !== 'anon.'){
$username = $username->getUsername();
}
$this->securityToken->setToken(null);
$this->session->getFlashBag()->set('error', 'Your session expired, you need to login again');
$this->session->invalidate();
$this->logger->makelog(//I get multiple log entries here instead of 1
0,
'Session timeout',
$username
);
$event->setResponse(new RedirectResponse($this->router->generate('login')));
}
}
}
}
UPD_1
我已经创建了一个logout侦听器,但是当按下logout
按钮时它只侦听Logout
事件,并且使用不同的日志条目记录此操作。在上面的代码中,我使用$this->session->invalidate()
来注销用户。我的注销侦听器代码如下:
<?php
namespace AppBundle\EventListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Http\Logout\LogoutHandlerInterface;
use Doctrine\ORM\EntityManager;
class LogoutListener implements LogoutHandlerInterface
{
protected $securityContext;
protected $entityManager;
protected $logger;
public function __construct(TokenStorage $securityContext, EntityManager $entityManager, $logger)
{
$this->securityContext = $securityContext;
$this->entityManager = $entityManager;
$this->logger = $logger;
}
public function logout(Request $Request, Response $Response, TokenInterface $Token)
{
$em = $this->entityManager;
$user = $this->securityContext->getToken()->getUser();
$this->logger->makelog(1, 'Logout action, logout button', $user);
}
}