<?php
namespace App\EventListener;
use Doctrine\DBAL\Connection;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
class AuthTokenSubscriber implements EventSubscriberInterface
{
/** @var Connection */
private $db;
public function __construct(Connection $db) { $this->db = $db; }
public static function getSubscribedEvents(): array
{
return [RequestEvent::class => 'onKernelRequest'];
}
public function onKernelRequest(RequestEvent $event): void
{
$req = $event->getRequest();
$session = $req->getSession();
$tokenRaw = $req->cookies->get('auth_token');
if ($session->has('hash') || $tokenRaw === null) {
return; // уже залогинен или cookie нет
}
/* фильтруем мусор/атаки */
if (!\is_string($tokenRaw) || !\preg_match('/^[a-f0-9]{64}$/', $tokenRaw)) {
return;
}
$tokenHash = hash('sha256', $tokenRaw);
$row = $this->db->fetchAssociative(
'SELECT hash FROM users WHERE auth_token_hash = ?', [$tokenHash]
);
if ($row) {
$session->migrate(true);
$session->set('hash', $row['hash']);
}
}
}