Сеансы Codeigniter умирают - программирование

Сеансы Codeigniter умирают

После небольшого использования (25 мин - 1,5 часа) в моей системе пользователи получают удар. По какой-то причине мои сеансы красивы. Я думаю, что cookie на стороне клиента как-то теряет идентификатор сеанса и создает новый. Я сохраняю данные сеанса на Database.

Это моя сессия conf:

        $config['sess_cookie_name']     = 'v2Session';
        $config['sess_expiration']      = 32400; //session will be 9 hours, for a shift.
        $config['sess_expire_on_close'] = FALSE;
        $config['sess_encrypt_cookie']  = TRUE;
        $config['sess_use_database']    = TRUE;
        $config['sess_table_name']      = 'ci_sessions';
        $config['sess_match_ip']        = TRUE;
        $config['sess_match_useragent'] = TRUE;
        $config['sess_time_to_update']  = 300;

Теперь, когда я смотрю в БД, я вижу несколько сеансов для каждого пользователя. Каждый удар означает новый сеанс, и старый сеанс не удаляется до истечения срока его действия. Когда сеанс "отключается", пользователям необходимо снова войти в систему.

Любая помощь по устранению неполадок будет оценена.

EDIT:

Итак, после некоторых исследований я заметил, что сеансы умирают, потому что session_id, которые сохраняются в cookie и session_id, которые сохраняются в Database, не совпадают. Я подозреваю, что это происходит, когда пользователь загружает по 2 страницы на другой вкладке/окне. Одна загрузка происходит только тогда, когда сеанс обновляет session_id и вторую нагрузку (которая убивает сеанс) старым session_id. Система ищет сеанс в Database и не находит его. Результат: Удар из системы + безумный пользователь.

Кто-нибудь испытал это? и есть ли у кого-нибудь идея о том, как это исправить?

4b9b3361

Ответ 1

Короткий ответ.

Не запускайте сеанс в нескольких экземплярах., просто проверьте существующие, если мы говорим об авторизации, а затем удалите пользователя на страницу AuthLogin, если сеанс не существует. Создайте класс/библиотеку Auth и позвольте ему обрабатывать вещи. Если сеанс не существует, он попросит создать другой.

Это не "множественные" сеансы, уникальный идентификатор сеанса - статистически случайная строка с очень сильной энтропией, хэшированная с MD5 для переносимости и регенерированная (по умолчанию) каждые пять минут)

- Проверить здесь в разделе Как работают сеансы?

Когда вы выполняете session_destroy, он уничтожает сеансы (несколько или одиночные), связанные с пользователем, из базы данных, а также истекает срок действия cookie. Да, плохой дизайн, я знаю!

Из вашего EDIT вопроса

Итак, после некоторых исследований я заметил, что сеансы умирают, потому что session_id, который сохраняется в файле cookie и session_id, который сохраненные в базе данных не совпадают. Я подозреваю, что это происходит, когда пользователь загружает по 2 страницы на другой вкладке/окне. Одна нагрузка происходит только тогда, когда сеанс обновляет session_id и второй load (который убивает сессию) старым session_id. Система ищет сессию в базе данных и не находит ее.

Открытие страницы в нескольких вкладках = Обновить на одной вкладке.

Вы настраиваете сеансы, не проверяя их существование? Пожалуйста, поделитесь своим script.

Я буду следить за этим ответом, пока мы не подумаем.

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

Уродливый хак

Задайте это как свою конфигурацию:

    $config['sess_cookie_name']     = 'v2Session';
    $config['sess_expiration']      = 32400; //session will be 9 hours, for a shift.
    $config['sess_expire_on_close'] = FALSE;
    $config['sess_encrypt_cookie']  = TRUE;
    $config['sess_use_database']    = TRUE;
    $config['sess_table_name']      = 'ci_sessions';
    $config['sess_match_ip']        = TRUE;
    $config['sess_match_useragent'] = TRUE;
    $config['sess_time_to_update']  = 32400; // Session will update in 9 hours.

Это единственная проблема... Однако при анализе того, что сеансы неправильно сопоставляются с базой данных, это ясно указывает, что при sess_time_to_update база данных может не обновлять соответствующий идентификатор... Однако это решение все равно будет предположением, если вы не попробуете его.

Ответ 2

Я также разработчик codeigniter. Я также применил ниже код в своем приложении: -

$config['sess_cookie_name']     = 'ci_session';
$config['sess_expiration']      = 300; // 7200
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie']  = true;
$config['sess_use_database']    = true;
$config['sess_table_name']      = TBL_SESSION;
$config['sess_match_ip']        = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update']  = 300;

В моем приложении через каждые 5 минут сеанс истекает. Я использую таблицу tbl_session для сохранения записи. Учитывая условие ниже 2, он отлично работает для моего приложения: -

1) opening application in firefox mozilla at 10:55 pm then it will take You in login screen at 11:00 pm.

2) at the same time , opening application in chrome browser at 10:56 pm  then it will take You in login screen at 11:05 pm.

1 вещь, о которой нужно помнить - приведенный выше код будет в вашем config.php, а в каждом контроллере вашего приложения будет проверка активности сеанса.

Ответ 3

почему бы вам не попробовать:

  • Проверьте, активен ли пользователь активным сеансом IF Session активен = ничего не делать все нормально

теперь, если у пользователя нет активного сеанса, вам нужно сделать 2 вещи

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

В. если сеанс неактивен и нет файлов cookie, вам нужно забрать его на страницу входа в систему

вот пример

<?php
$expire=time()+60*60*24*30;
setcookie("user", "Login_USERNAME", $expire);
?>

В приведенном выше примере время истечения устанавливается на месяц (60 секунд * 60 мин * 24 часа * 30 дней).

ok теперь вы должны получить файлы cookie

    <?php
///Check if session alive or not
if (!empty($_SESSION['user'])){
     //Do Nothing the user is logged in 

    }
///There is Cookies BUT No Session
elseif (isset($_COOKIE["user"]) && empty($_SESSION['user'])){
      // Here you can see that there is cookies on the user PC and at the same time the Session is Not active so you should make session start and make user auto login again
    }

///There is no Cookies and Session is not alive
    elseif (!isset($_COOKIE["user"]) && empty($_SESSION['user'])){
      // Here you can see that there is No cookies and at the same time the Session is Not active so you should take user to login page
    }
?>

Вот оно, и вам нужно организовать его с помощью собственного кода, но это способ сделать это!

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

Ответ 4

У меня была та же проблема, это состояние конфигурации помогло:

$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 604800; // 604800 = 1 week
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 604800; // 604800 = 1 week

sess_time_to_update должен быть таким же, как sess_expiration

sess_encrypt_cookie должен быть FALSE

Ответ 5

Из документы в разделе Как работают сеансы?

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

Пробовали ли вы использовать функцию ведения журнала кода Igniter, чтобы узнать, намеренно ли создан модуль сеанса для создания новых сеансов? Более конкретно, вы, вероятно, захотите выполнить некоторую отладку в классе CI_Session (system/libraries/Session.php).

В sess_read есть 2 места, где CI определит, что текущий сеанс отсутствует. Если вы включите ведение журнала, в документах, вы увидите, что CI попадает в эти условия

CI_Session:: sess_read (условие 1)

// Fetch the cookie
$session = $this->CI->input->cookie($this->sess_cookie_name);

// No cookie?  Goodbye cruel world!...
if($session === FALSE)
{   
    log_message('debug', 'A session cookie was not found.');
    return FALSE;
}

CI_Session:: sess_read (условие 2)

// encryption was not used, so we need to check the md5 hash
$hash    = substr($session, strlen($session)-32); // get last 32 chars
$session = substr($session, 0, strlen($session)-32);

// Does the md5 hash match?  This is to prevent manipulation of session data in userspace
if ($hash !==  md5($session.$this->encryption_key))
{
    log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
    $this->sess_destroy();
    return FALSE;
}  

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

Ответ 6

У меня была такая же проблема с запуском нескольких приложений в одной установке CI. После нескольких часов отладки по строке с помощью xdebug я обнаружил, что каждое приложение в Codeigniter имеет отдельный сеанс. Чтобы устранить ошибку, я предоставил отдельное имя в каждом файле config.php.

Файл один,

$config['sess_cookie_name']     = 'ci_session1';

Файл два

$config['sess_cookie_name']     = 'ci_session2';

Файл три

$config['sess_cookie_name']     = 'ci_session3';

Ответ 7

в файле $config.php

change  $config['sess_expiration'] = 7200;

до

$config['sess_expiration'] = 604800; // one week

Ответ 8

вы можете использовать базовый php-код

ini_set('session.gc_maxlifetime', 32400);