Регенерация идентификатора сеанса работает при входе в систему - выводит меня из текущего сеанса при последующих запусках - PullRequest
0 голосов
/ 29 марта 2019

У меня есть этот механизм входа в систему с дополнительным барьером аутентификации, представленным перед тем, как пользователь может изменить конфиденциальную информацию (такую ​​как пароль, адрес электронной почты и т. Д.) Через свой профиль.

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

Для процесса входа в систему все идет хорошо.Идентификатор сеанса до и после входа в систему различны.Здесь нет проблем.Проблема начинается, когда я захожу в authentic.php, который служит барьером, представляемым пользователям, прежде чем они смогут изменить свой пароль.После успешной проверки предоставленного пароля по хешу из базы данных я бы установил новую переменную сеанса с именем «authenticated», которая дает доступ к следующей странице, pass-change.php.Прежде чем установить «authenticated», идентификатор сеанса должен быть снова восстановлен.

Вот в чем моя проблема.

Вместо того, чтобы перевести меня на pass-change.php с новым сеансомID, он уничтожает сеанс;следовательно, я возвращаюсь в login.php, предположительно потому, что $ _SESSION ['loggedin'] больше не установлен.

// Это моя функция session_start ()

    function my_session_start() {
      session_start();
      if (isset($_SESSION['destroyed'])) {
         // checks if session has been 'destroyed' for more than 5 minutes
         if ($_SESSION['destroyed'] < time() - 300) {
           // if true, wipe all session variables and throw exception
           $_SESSION = array();
           throw new Exception('This session is obsolete');
         }
         if (isset($_SESSION['new_session_id'])) {
           // if new_session_id is still set, close the session and attempt to start a new session with it
           session_commit();
           session_id($_SESSION['new_session_id']);
           session_start();
           return;
         }
      }
    }
    my_session_start();

// Это моя функция session_regenerate_id ()

    function my_session_regenerate_id() {
      // new session ID is created and stored for later use
      $new_session_id = session_create_id();
      $_SESSION['new_session_id'] = $new_session_id;
      // set the current session as 'destroyed' and save current time
      $_SESSION['destroyed'] = time();
      // close session
      session_commit();
      // set the new ID we created previously and start a new session
      session_id($new_session_id);
      ini_set('session.use_strict_mode', '0');
      session_start();
      ini_set('session.use_strict_mode', '1');
      // unset these variables as they should not be with the new session
      unset($_SESSION['destroyed']);
      unset($_SESSION['new_session_id']);
    }

// Сессии всегда начинаются в начале каждого файла.my_session_regenerate_id () вызывается непосредственно перед тем, как я определяю переменные сеанса, содержащие флаги аутентификации или пользовательские данные.Это делается в файле login.php после проверки пароля по хешу и считается правильным;и также вызывается в authentication.php после того, как пользователь предоставил свой правильный пароль.

// это часть, где я вызываю my_session_regenerate_id () для authentication.php

if (password_verify($pass, $hash)) {
    my_session_regenerate_id();
    $_SESSION["authenticated"] = time();
    header('Location: pass-change.php');
}

// некоторые страницыперенаправление, когда вы не вошли в систему

if (!isset($_SESSION["loggedin"])) {
    header('Location: login.php');

Я ожидаю, что сессия сохранит свой статус после вызова my_session_regenerate_id () в authentication.php, но он будет уничтожен.Все, что нужно сделать: установить текущий сеанс как «уничтоженный», создать новый идентификатор сеанса и изменить его, сохранив при этом все остальные пользовательские данные и флаги аутентификации, такие как $ _SESSION ['loggedin'].

РЕДАКТИРОВАТЬ

По запросу, вот результаты печати всех данных переменных сеанса:

Перед входом в систему, на login.php:

array(2) {
  ["usertoken"]=>
  string(64) "519f82f974fb8e79b30ee950be9ba63048278105bd8e983fa832e754aaf47b3c"
  ["usrtokentime"]=>
  int(1553865620)
}

После первого запуска регенерации идентификатора сеанса в файле profile.php:

Идентификатор сеанса изменился после входа в систему

array(7) {
  ["lastLogin"]=>
  int(1553864997)
  ["loggedin"]=>
  string(0) ""
  ["registerDate"]=>
  int(1553605077)
  ["name"]=>
  string(14) "User Name"
  ["email"]=>
  string(26) "user.email@gmail.com"
  ["type"]=>
  string(1) "A"
  ["usertoken"]=>
  string(0) ""
}

Второй запускрегенерация идентификатора сеанса.После отправки формы по адресу authentication.php и возвращения в login.php:

Идентификатор сеанса снова изменился

array(3) {
  ["authenticated"]=>
  int(1553865804)
  ["usertoken"]=>
  string(64) "ba454364870f5d8cdfd4e5a3213d3a34117f161c098c97060e70327d3a983501"
  ["usrtokentime"]=>
  int(1553865804)
}

Таким образом, выжила только «аутентифицированная» переменная сеанса.Все остальные были уничтожены.

1 Ответ

0 голосов
/ 29 марта 2019

Благодаря 04FS я смог точно определить проблему.

Функция my_session_regenerate_id () стирает все переменные сеанса при ее вызове. Решение состоит в том, чтобы установить все переменные после вызова функции, и это было легко сделать в моем коде, потому что на тот момент уже был доступен подготовленный объект оператора для извлечения всех данных.

Вот так теперь выглядит код вызова моей функции для authentication.php:

if (password_verify($pass, $hash)) {
    my_session_regenerate_id();
    $_SESSION["authenticated"] = time();
    $_SESSION["lastLogin"] = $res['lastLogin'];
    $_SESSION["loggedin"] = "";
    $_SESSION["registerDate"] = $res['registerDate'];
    $_SESSION["name"] = $res['name'];
    $_SESSION["email"] = $res['email'];
    $_SESSION["type"] = $res['type'];
    $_SESSION["usertoken"] = "";
    header('Location: pass-change.php');
}
...