постоянный вход с Zend_Session :: запомнитьMe - PullRequest
11 голосов
/ 02 марта 2012

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

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

По сути, функция RememberMe просто расширяетсядата окончания активного сеанса, что означает, что если пользователь использует опцию запомнить меня, он будет оставаться в системе в течение 2 недель с активным сеансом.

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

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

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

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

Ответы [ 2 ]

10 голосов
/ 02 марта 2012

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

Конечно, могут быть непредвиденные последствия, если кто-то произвольно установит его на очень большое значение, но Следует отметить, что данные сеанса по-прежнему подлежат сборке мусора на основе 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.

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

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

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

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

3 голосов
/ 02 марта 2012

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...