based on this question
I have implemented an automatic logout of users after a certain period of inactivity (like in question above). This works fine, but I need to make a log entry for this event.
The problem is that when logout fires, I get multiple records in my log file instead of 1 record. I guess I need to listen to some other request, instead of onKernelRequest
. Any ideas how to do that? My code is as follows:
<?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
I have already created a logout listener, but it listens only for logout
event when the Logout
button is pressed and this action is logged with different log entry. In my code above I use $this->session->invalidate()
in order to logout the user. My code for logout listener is as follows:
<?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);
}
}