Постоянный вход в систему с Zend_Session:: запомнить Me
Я использую Zend_Session
чтобы управлять своими пользовательскими сессиями, и я искал в своем приложении опцию "Запомнить меня", чтобы пользователи оставались в системе в течение 2 недель или около того.
Я заметил что Zend_Session
уже имеет встроенную функцию под названием Zend_Session::rememberMe
Однако я не уверен, что эта логика функции правильна для использования в качестве постоянного входа в систему.
По сути, функция Remember Me просто продлевает дату окончания активного сеанса, что означает, что если пользователь использует опцию запомнить меня, он будет оставаться в системе в течение 2 недель с активным сеансом.
Это поднимает 2 основных вопроса.
- Я храню сеансы в базе данных, что означает, что все эти неактивные пользователи хранятся в моей сеансовой таблице в течение 2 недель. У меня более 50 тыс. Неактивных сессий, и это снижает производительность приложения.
- Я хочу знать, вернулся ли пользователь на сайт после 24 часов бездействия, и подтвердить свою информацию. Поскольку его сеанс остается открытым, я не могу точно сказать, вернулся ли он через 1 час или 1 неделю, поскольку у него такой же активный идентификатор сеанса.
Я читал, что если я хочу реализовать функцию запомнить меня, я не должен использовать для этого куки-файл сессии, и мне нужно создать еще один "куки-файл для входа в систему", чтобы запомнить хэшированный user_id и токен. Вот полное объяснение: Каков наилучший способ реализовать "запомни меня" для веб-сайта?
Так почему же Zend Framework предлагает такую функцию, если ее использование может создать проблемы с производительностью и безопасностью?
2 ответа
+1 за то, что обратил внимание на главный недостаток подхода Zend к функции "запомнить меня". Некоторые люди не понимают, что при попытке продлить время жизни сеанса необходимо наложить штраф, независимо от того, является ли обработчик сеанса файловым или основанным на дБ. Разрешить сохранение устаревших сеансов за пределами разумных временных рамок - слабое решение, и вам лучше реализовать собственное решение для файлов cookie, описанное по указанной вами ссылке.
Прямой ответ на ваш вопрос; кто знает. Возможно, они не учитывали тот факт, что многие пользователи выбирают обработку сеансов базы данных, и полагали, что накопление устаревших файлов cookie сеансов в файловой системе не оказало прямого влияния на производительность.
Кроме того, если вы хотите отследить, вернулся ли пользователь и восстановил устаревший сеанс, вы можете добавить столбец updated_at в таблицу отслеживания сеансов. Итак, у вас будет два столбца отметок времени; создаются и обновлены, что поможет вам сделать это определение.
Можно только предположить, почему они предложили эту функцию, но я не вижу и серьезных причин, чтобы она была недоступна. Множество языков программирования дают вам возможность делать что-то плохое или писать код, который имеет непредвиденные побочные эффекты.
Конечно, могут быть непредвиденные последствия, если кто-то произвольно установит для него очень большое значение, но следует отметить, что данные сеанса по-прежнему подлежат сборке мусора на основе session.gc_maxlifetime независимо от rememberMe
время, установленное на печенье. призвание 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
установлено в.
Чтобы ответить на ваши 2 вопроса:
Что касается вашей первой проблемы, я бы задал вопрос, почему наличие 50000 неактивных сессий снижает производительность. Если база данных правильно проиндексирована по идентификатору сеанса, она должна быть очень быстрой для получения данных сеанса, даже если в базе данных были миллионы сеансов. Возможно, вы столкнулись с аппаратным ограничением? Выбор данных из 50000 записей, когда все сделано правильно, должен иметь небольшие накладные расходы.
Что касается вашего второго вопроса, я согласен с Майком, вы должны сохранить значение сеанса, указывающее, когда был последний визит, таким образом, когда вы начинаете сеанс, вы можете проверить их последний визит и посмотреть, сколько времени прошло с момента их последней страницы. Посмотреть. Затем, основываясь на вашем пороговом значении, вы можете определить, возвращаются ли они на ваш сайт после неактивности.
По соображениям безопасности, если вы обнаружите, что с момента их последнего посещения прошло так много времени, сейчас самое время перезвонить. rememberMe()
Это также приведет к созданию нового файла cookie и поможет предотвратить перехват сеанса и его фиксацию.