Как я могу обновить сеанс во время запроса POST? - PullRequest
6 голосов
/ 23 декабря 2011

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

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

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

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

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

Ответы [ 2 ]

9 голосов
/ 24 декабря 2011

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

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

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

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

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

2 голосов
/ 24 апреля 2014

Чтобы изложить все, что здесь готово, вот полный рабочий пример, зарегистрированный в качестве прослушивателя запросов ядра. Для этого примера я жестко запрограммировал время ожидания до 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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...