Zend_Session и срок действия

Мне нужно установить очень короткий сеанс (3 минуты) при переходе на определенную страницу моего сайта. Если кто-то снова откроет эту страницу в течение этого трехминутного сеанса, сеанс должен обновиться, чтобы истечь через 3 минуты после этого времени.

На моем «загрузочном устройстве» (это не типичный загрузчик Zend, но он присутствует на каждой странице) я делаю следующее:

$aSessionSaveHandlerConfig = array
(
    "name"           => "Sessions",
    "primary"        => "Session_ID",
    "modifiedColumn" => "UpdateTimestamp",
    "dataColumn"     => "Data",
    "lifetimeColumn" => "Lifetime",
);

$oSaveHandler = new Zend_Session_SaveHandler_DbTable($aSessionSaveHandlerConfig);
$oSaveHandler->setLifetime(App::$ReservationTimeout)->setOverrideLifetime(true);    

Zend_Session::setSaveHandler($oSaveHandler);

ini_set("session.cookie_lifetime",App::$ReservationTimeout);

$aSessionOptions = array
(
    "gc_probability"    => 100,
    "gc_divisor"        => 100,
    "gc_maxlifetime"    => App::$ReservationTimeout,
    "cookie_lifetime"   => App::$ReservationTimeout,
);

Zend_Session::setOptions($aSessionOptions);

Затем на странице, которая должна создать/обновить сеанс, у меня есть:

App::$ReservationSession = new Zend_Session_Namespace("ReservationSession");
$oSaveHandler = Zend_Session::getSaveHandler();
$oSaveHandler->setLifetime(App::$ReservationTimeout);

Я вижу записи в базе данных, столбец времени жизни правильный, но если я неоднократно попадаю на страницу, которая создает/обновляет сеанс, я получаю новый идентификатор сеанса через 3 минуты (а другой удаляется после сборки мусора.

Похоже, проблема заключается в том, чтобы файл cookie обновлял свое время. Есть идеи?


person Travis    schedule 28.03.2012    source источник


Ответы (1)


Чтобы обновить срок действия файла cookie сеанса, вы можете использовать Zend_Session::rememberMe(), чтобы изменить время жизни файла cookie по умолчанию. Вызов rememberMe() также приведет к вызову Zend_Session::regenerateId(), который генерирует новый идентификатор сеанса, копирует данные старого сеанса в новый сеанс и отправляет новый файл cookie сеанса в браузер.

Попробуйте следующий код и посмотрите, решит ли он вашу проблему:

App::$ReservationSession = new Zend_Session_Namespace("ReservationSession");
$oSaveHandler = Zend_Session::getSaveHandler();
$oSaveHandler->setLifetime(App::$ReservationTimeout);

// Call remember me which will send a new session cookie with 3 minute expiration
// from the current time.  Old session data is copied to the new one and the old
// session is deleted
Zend_Session::rememberMe(App::$ReservationTimeout);

См. раздел руководства по идентификаторам сеанса для получения дополнительной информации или см. также Как сбросить функцию Zend RememberMe при каждом автоматическом входе в систему?

ОБНОВЛЕНИЕ: Учитывая ваш комментарий, я придумал это решение, которое вы можете использовать.

Что это делает, так это запускает ваш сеанс как обычно, а затем проверяет значение в сеансе, чтобы увидеть, был ли у пользователя существующий сеанс.

Если у них есть сеанс, он использует setcookie() для отправки обновленного файла cookie сеанса с использованием существующих параметров (включая идентификатор сеанса), за исключением того, что он устанавливает срок действия time() + $ReservationTimeout. Если у них не было сеанса, то нет необходимости обновлять файл cookie, поскольку срок его действия уже правильный, и он будет обновлен при их следующем запросе (при условии, что они посетят его до истечения срока его действия).

App::$ReservationSession = new Zend_Session_Namespace("ReservationSession");
$oSaveHandler = Zend_Session::getSaveHandler();
$oSaveHandler->setLifetime(App::$ReservationTimeout);

if (!isset(App::$ReservationSession->hasSession)) {
    // user had no session before or it was expired
    App::$ReservationSession->hasSession = true;
} else {
    // user has a valid session, update the cookie to expire 3 mins from now
    $params = session_get_cookie_params();
    $expire = time() + App::$ReservationTimeout;

    setcookie(session_name(),
              Zend_Session::getId(),
              $expire,
              $params['path'],
              $params['domain'],
              $params['secure'],
              $params['httponly']);
}

Я протестировал решение с помощью обработчика сеанса файлов, и оно сработало, как и ожидалось, я думаю, что оно должно подойти и для вашей ситуации.

person drew010    schedule 28.03.2012
comment
Потрясающее объяснение, но у меня есть ограничения внешнего ключа MySQL InnoDB с использованием идентификатора сеанса, поэтому необходимо сохранить тот же идентификатор сеанса при обновлении тайм-аута. Можно ли сделать то, что делает RememberMe, без изменения идентификатора сеанса? - person Travis; 29.03.2012