src/EventListener/AuthTokenSubscriber.php line 32

Open in your IDE?
  1. <?php
  2. namespace App\EventListener;
  3. use Doctrine\DBAL\Connection;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\HttpKernel\Event\RequestEvent;
  6. class AuthTokenSubscriber implements EventSubscriberInterface
  7. {
  8.     /** @var Connection */
  9.     private $db;
  10.     public function __construct(Connection $db) { $this->db $db; }
  11.     public static function getSubscribedEvents(): array
  12.     {
  13.         return [RequestEvent::class => 'onKernelRequest'];
  14.     }
  15.     public function onKernelRequest(RequestEvent $event): void
  16.     {
  17.         $req      $event->getRequest();
  18.         
  19.         if ($req->getPathInfo() === '/logout') {
  20.             return; 
  21.         }
  22.         
  23.         $session  $req->getSession();
  24.         $tokenRaw $req->cookies->get('auth_token');
  25.         if ($session->has('hash') || $tokenRaw === null) {
  26.             return;                                // уже залогинен или cookie нет
  27.         }
  28.         /* фильтруем мусор/атаки  */
  29.         if (!\is_string($tokenRaw) || !\preg_match('/^[a-f0-9]{64}$/'$tokenRaw)) {
  30.             return;
  31.         }
  32.         $tokenHash hash('sha256'$tokenRaw);
  33.         $row $this->db->fetchAssociative(
  34.             'SELECT hash FROM users WHERE auth_token_hash = ?', [$tokenHash]
  35.         );
  36.         if ($row) {
  37.             $session->migrate(true);
  38.             $session->set('hash'$row['hash']);
  39.         }
  40.     }
  41. }