Как обновить сеанс во время запроса POST?

Я создаю приложение Ajax в Symfony2, где пользователь входит в систему, а затем с этого момента все обрабатывается POST-запросами. После определения времени жизни сеанса до 5 минут в config.yml , я столкнулся с проблемой недействительности сеанса пользователя через 5 минут, даже несмотря на то, что они делают запросы POST. Каждый раз, когда делается запрос, я хотел бы сбросить обратный отсчет до того, как сессия недействительна, но я не уверен, как это сделать эффективно.

Метод, о котором я сейчас думаю, – это написать слушатель для события kernel.request , проверить, является ли метод запроса POST, и манипулировать классом сеанса. Я еще этого не делал, но это не похоже на чистое решение, так как слушателю нужно стрелять каждый раз, когда делается запрос.

Вот моя конфигурация сеанса:

 session: default_locale: %locale% auto_start: true lifetime: 300 

Есть идеи? Является ли решение простым PHP, а не Symfony?

Продолжительность сеанса – это максимальный возраст. Это контролируется с помощью уже созданного файла cookie, который больше не обновляется со стороны сервера (поскольку сеанс уже установлен). Вы можете просто обновить этот файл cookie вручную, и я думаю, что это сделает его с symfony2.

Вероятно, проще всего восстановить идентификатор сеанса без разрушения сеанса:

 $this->get('session')->migrate(); 

Это должно вызвать обновление в cookie сеанса.

Вероятно, связанные вопросы:

  • Время сеанса symfony2
  • Программно установить срок службы сеанса в Symfony2

Чтобы изложить все, что здесь готово, вот полный рабочий пример, зарегистрированный как слушатель запросов ядра. В этом примере я запрограммировал тайм-аут на 1200 секунд (20 минут). Вы можете передать количество времени из файла parameters.yml (что я и делал в процессе производства):

 #src\My\AppBundle\Resources\config\services.yml kernel_request.listener: class: My\AppBundle\EventListener\KernelRequestListener tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } arguments: [@security.context, 1200] 

И класс:

 #Place in your src\My\AppBundle\EventListener folder namespace My\AppBundle\EventListener { use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\HttpKernel; use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; use Symfony\Component\Security\Core\Exception\CredentialsExpiredException; use Symfony\Component\Security\Core\SecurityContextInterface; class KernelRequestListener { /** @var int */ private $maxIdleTime; /** @var SecurityContextInterface */ private $securityContext; function __construct(SecurityContextInterface $securityContext, $maxIdleTime) { $this->securityContext = $securityContext; $this->maxIdleTime = $maxIdleTime; } public function onKernelRequest(GetResponseEvent $event) { if ($event->getRequestType() !== HttpKernel::MASTER_REQUEST) { // don't do anything if it's not the master request return; } $session = $event->getRequest()->getSession(); $token = $this->securityContext->getToken(); if ($session !== null && !($token instanceof AnonymousToken) && $token->isAuthenticated()) { $session->start(); if ((time() - $session->getMetadataBag()->getLastUsed()) > $this->maxIdleTime) { throw new CredentialsExpiredException(); } $session->migrate(false, $this->maxIdleTime); } } }