<?php
namespace App\EventSubscriber;
use App\Entity\User;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
class SessionIdleSubscriber implements EventSubscriberInterface
{
protected $session;
protected $tokenStorage;
protected $router;
protected $sessionIdleTime;
protected $flashBag;
public function __construct(
SessionInterface $session,
TokenStorageInterface $tokenStorage,
RouterInterface $router,
ParameterBagInterface $params,
FlashBagInterface $flashBag
) {
$this->session = $session;
$this->tokenStorage = $tokenStorage;
$this->router = $router;
$this->sessionIdleTime = $params->get('session_idle_time') ?? 0; //$sessionIdleTime equal to session_idle_time if is defined in parameters section, zero else
$this->flashBag = $flashBag;
}
public function onKernelRequest(RequestEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST != $event->getRequestType()) {
return;
}
if ($this->sessionIdleTime > 0) {
// Get the difference between now and the time of last action make it by user
$lapse = time() - $this->session->getMetadataBag()->getLastUsed();
if (null !== $this->tokenStorage->getToken() && "anon." !== $this->tokenStorage->getToken()->getUser()) {// if user is logged in
$roles = $this->tokenStorage->getToken()->getUser()->getRoles();
if ($lapse > $this->sessionIdleTime && true === in_array("ROLE_APP",$roles)) {
$this->tokenStorage->setToken(null);
//$this->flashBag->add('danger', "session destroy");
if($event->getRequest()->isXmlHttpRequest()){
throw new AccessDeniedHttpException('Session Expired.');// return status 403 for ajax call
} else {
$event->setResponse(new RedirectResponse($this->router->generate('app_page_index')));
}
}
}
}
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [
// must be registered before (i.e. with a higher priority than) the default Locale listener
KernelEvents::REQUEST => [['onKernelRequest', 1]]
];
}
}