постоянный вход с Zend_Session :: rememberMe

Я использую Zend_Session для управления моими пользовательскими сеансами, и я пытался реализовать опцию «Запомнить меня» в моем приложении, чтобы пользователи регистрировались в течение 2 недель или около того.

Я заметил, что Zend_Session уже имеет встроенную функцию Zend_Session::rememberMe , однако я не уверен, правильна ли эта логика функций для использования в качестве сохраненного входа.

По сути, функция rememberMe просто увеличивает срок действия активного сеанса, а это означает, что если пользователь использует опцию «запомнить меня», он будет оставаться в системе в течение 2 недель с активной сессией.

Это вызывает две основные проблемы.

  1. Я храню сессии в базе данных, а это означает, что все эти неактивные пользователи хранятся в течение 2 недель в моей таблице сеансов. У меня более 50 тыс. Неактивных сессий, и это вредит производительности приложения.
  2. Я хочу знать, вернулся ли пользователь на сайт после 24 часов бездействия и повторно подтвердил свою информацию. Поскольку его сеанс остается открытым, я не могу сказать, вернулся ли он через 1 час или 1 неделю, так как он имеет тот же самый активный идентификатор сеанса.

Я читал, что если я хочу реализовать функцию «запомнить меня», я не должен использовать для нее cookie сеанса, и я должен создать еще один «cookie для входа», чтобы запомнить хешированный user_id и токен. вот полное объяснение: какой лучший способ реализовать «запомнить меня» для веб-сайта?

Итак, почему платформа zend предлагает такую ​​функцию, если ее использование может создать проблемы с производительностью и безопасностью?

Solutions Collecting From Web of "постоянный вход с Zend_Session :: rememberMe"

+1, отметив главный недостаток подхода Zend к функциональности «запомнить меня». Некоторые люди не понимают, что существует наказание, когда они пытаются продлить время жизни сеанса, независимо от того, какой обработчик сеанса является файлом или db. Разрешение устаревших сессий сохраняется за разумные временные рамки – это слабое решение, и вам лучше реализовать пользовательское решение cookie, описанное в приведенной вами ссылке.

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

Кроме того, если вы хотите отслеживать, вернулся ли пользователь и восстановил устаревший сеанс, вы можете добавить столбец «updated_at» в таблицу отслеживания сеансов. Итак, у вас будет две столбца временной метки; created_at и updated_at, что поможет вам сделать это определение.

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

Несомненно, могут быть непредвиденные последствия, если кто-то произвольно устанавливает его на очень большое значение, но следует отметить, что данные сеанса по-прежнему подлежат сборке мусора на основе session.gc_maxlifetime, независимо от времени rememberMe установленного в cookie. Вызов Zend_Session::rememberMe() не влияет на сбор мусора для этих данных.

Рассмотрим следующее:

Bootstrap.php

 protected function __initSession() { ini_set('session.gc_maxlifetime', 45); // set session max lifetime to 45 seconds ini_set('session.gc_divisor', 1); // 100% chance of running GC Zend_Session::start(); } 

IndexController.php

 public function indexAction() { $data = new Zend_Session_Namespace('data'); if (!isset($data->time)) { // no active session - set cookie lifetime and set some data Zend_Session::rememberMe(90*86400); // 90 days $data->time = time(); echo "Setting time"; } else { echo date('r', $data->time); } } 

Если бы вы получили доступ к IndexController , то в первый раз вы увидите Setting time . Затем, если вам нужно подождать более 45 секунд, вы увидите распечатанное время и (в моем случае) по следующему запросу, срок действия которого истек. Данные сеанса удаляются с сервера, и хотя у меня все еще есть предыдущий файл cookie, он больше не распознается сервером.

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

Чтобы ответить на ваши 2 вопроса:

Что касается вашего первого вопроса, я бы поставил под вопрос, почему 50 000 неактивных сеансов ухудшают производительность. Если база данных должным образом проиндексирована в идентификаторе сеанса, она должна быть чрезвычайно быстрой для получения данных сеанса, даже если в базе данных было миллионы сеансов. Возможно, вы попали в аппаратное ограничение? Выбор данных из 50 000 записей при правильном выполнении должен иметь небольшие накладные расходы.

Что касается вашей второй проблемы, я согласен с Майком, вы должны сохранить значение сеанса, указывающее, когда был последний визит, таким образом, когда вы начинаете сеанс, вы можете проверить их последний визит и посмотреть, сколько времени прошло со времени их последней страницы Посмотреть. Затем, основываясь на своем пороге, вы можете определить, возвращаются ли они на ваш сайт после того, как они неактивны.

По соображениям безопасности, если вы обнаружите, что это было так давно с момента их последнего посещения, это подходящее время для повторного вызова функции rememberMe() , так как это приведет к выпуску нового файла cookie и предотвратит захват и фиксацию сеанса.