<?php
namespace App\EventListener;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter;
class SessionIdleListener
{
/**
* @var int
*/
private $maxIdleTime;
/**
* @var AuthorizationChecker
*/
private $authChecker;
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* @var SessionInterface
*/
protected $session;
/**
* @var RouterInterface
*/
protected $router;
public function __construct(
string $maxIdleTime,
AuthorizationChecker $authChecker,
TokenStorageInterface $tokenStorage,
SessionInterface $session,
RouterInterface $router
) {
$this->maxIdleTime = (int) $maxIdleTime;
$this->authChecker = $authChecker;
$this->tokenStorage = $tokenStorage;
$this->session = $session;
$this->router = $router;
}
public function onKernelRequest(RequestEvent $event): void
{
if (!$event->isMasterRequest()
|| $this->maxIdleTime <= 0
|| $this->isAuthenticatedAnonymously()) {
return;
}
$this->session->start();
if ((time() - $this->session->getMetadataBag()->getLastUsed()) <= $this->maxIdleTime) {
return;
}
$this->tokenStorage->setToken(null);
/** @var FlashBag $flashBag */
$flashBag = $this->session->getBag('flashes');
$flashBag->set('info', "Vous avez été déconnecté pour cause d'inactivité.");
$this->session->invalidate();
$event->setResponse(new RedirectResponse($this->router->generate('app_login')));
}
private function isAuthenticatedAnonymously(): bool
{
return !$this->tokenStorage->getToken()
|| !$this->authChecker->isGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY);
}
}