src/EventSubscriber/IdleActivitySubscriber.php line 21

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  4. use Symfony\Component\HttpKernel\Event\RequestEvent;
  5. use Symfony\Component\HttpKernel\KernelEvents;
  6. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  7. use Symfony\Component\HttpFoundation\RedirectResponse;
  8. use Symfony\Component\Routing\RouterInterface;
  9. use Symfony\Component\HttpFoundation\JsonResponse;
  10. class IdleActivitySubscriber implements EventSubscriberInterface
  11. {
  12.     private int $maxIdle;
  13.     public function __construct(private TokenStorageInterface $tokens, private RouterInterface $router, int $minutes=20)
  14.     { $this->maxIdle = $minutes*60; }
  15.     public static function getSubscribedEvents(): array
  16.     { return [KernelEvents::REQUEST => ['onKernelRequest', 7]]; }
  17.     public function onKernelRequest(RequestEvent $event): void
  18.     {
  19.         if(!$event->isMainRequest()) return;
  20.         $req = $event->getRequest();
  21.         $session = $req->getSession();
  22.         if(!$session || !$this->tokens->getToken()) return;
  23.         $path = $req->getPathInfo();
  24.         if (preg_match('#^/login$#',$path)) return;
  25.         $last = $session->get('last_activity');
  26.         $now = time();
  27.         if($last && ($now - $last) > $this->maxIdle) {
  28.             $session->invalidate();
  29.             if(str_starts_with($path, '/api')) {
  30.                 $event->setResponse(new JsonResponse(['error'=>'session_expired'], 401));
  31.             } else {
  32.                 $event->setResponse(new RedirectResponse($this->router->generate('app_login')));
  33.             }
  34.             return;
  35.         }
  36.         $session->set('last_activity', $now);
  37.     }
  38. }