Безопасно ли сбрасывать, а не уничтожать сеанс php? - PullRequest
0 голосов
/ 29 апреля 2020

Я строю систему входа / выхода из системы, используя сеансы, и сталкиваюсь с проблемой, связанной с завершением работы пользователя для функций выхода из системы / тайм-аута. Это связано с тем, как я построил страницу, на которой работают эти функции.

Страница построена из центрального фрейма для реальных страниц, окруженного верхней панелью навигации и двумя боковыми панелями для навигации. Боковые панели состоят из нескольких элементов PHP, каждый из которых проверяет, установлен ли $ _SESSION ["idUser"], а функция jQuery обновляет элементы, чувствительные к состоянию входа в систему (меню и контент только для входа в систему). ) при нажатии c элементов. Я построил его таким образом, потому что страница обрабатывает браузерную игру, и я хочу, чтобы пользователь оставался на одном URL-адресе (без постоянных ссылок на любой игровой контент).

Вход / выход из системы кнопки обрабатываются jQuery, который отправляет запрос AJAX в файл PHP, который обрабатывает все проверки пользователя и обновляет элементы боковой панели. Когда пользователь входит в обработчик, заново генерирует идентификатор сеанса (поскольку страница не обновляется, идентификатор сеанса в противном случае не изменился бы, если бы пользователь вышел из системы и снова вошел в нее в том же сеансе, из моего опыта на данный момент). Таким образом, независимо от того, что произойдет, при входе в систему старый идентификатор сессии теряется. При выходе из системы обработчик PHP сбрасывает переменные $ _SESSION и затем уничтожает сеанс.

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

Проблема в том, что форма входа является одной из элементы боковой панели, которые перезагружаются скриптом jQuery на кнопке. Сценарий jQuery сначала отправляет запрос AJAX обработчику PHP, а затем заказывает перезагрузку элементов боковой панели. Тем не менее, jQuery не ожидает перезагрузки содержимого, если я добавляю .done () после части .load (), что означает, что я не могу использовать ту же самую функцию jQuery, чтобы поместить какой-либо текст в логин формы, потому что jQuery будет пытаться добавить текст еще до того, как форма будет загружена на страницу.

Единственное решение, которое я до сих пор придумала, - не уничтожать сеанс, а вместо этого установить $ _SESSION ["response"] = "logged out", затем форма входа отображает это значение.

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

jQuery код:

$(".column").on("click", "#login, #logout", function () { //This handles the login/logout buttons
    var formData = $(event.target).parent().parent().serialize(); //put the form data in a string
    if (formData !== "") { formData += "&"; } 
    formData += event.target.id + "=" + event.target.id; 
    $.post("/backend/validateUser.php", formData) //post the login/logout data to the handler file
    .done(function() { //refesh navbar and all sidebars
        $(".navbar, #sidebartopl, #sidebartopr, #sidebarbottoml, #sidebarbottomr").each(function(){
            $(this).load("/layout/"+$(this).attr("phpsource")+".php");
        });
    })
    if ($(this).attr("id") === "login") {
        $(".navbar").removeClass("collapsed");
    } else if ($(this).attr("id") === "logout") {
        $(".navbar").addClass("collapsed");
    }
});

PHP обработчик:

<?php declare(strict_types=1);

session_start();

include(database connection php);

$userName = $userPass = $userPass_1 = $userPass_2 = $email = $password = $errUser = $errEmail = $errPass_1 = $errPass_2 = $errTOS = ""; 
$TOS = false;
$timestamp = date("Y-m-d H:i:s", time());

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (isset($_POST["login"])) {                                  //LOGIN CODE

        session_regenerate_id();

        //check whether the user has filled in username and password, md5 the password, check the user's data in the database, then return their user ID and a whole bunch of variables which are saved to $_SESSION[]:

        session_regenerate_id();

        if (empty($_POST["username"])) {
            $_SESSION["response"]  = "ENTER USERNAME";
        } elseif (empty($_POST["password"])) {
            $_SESSION["response"] = "ENTER PASSWORD";
        } else {

            //everything filled in, consult the database:

            $userPass = test_input($_POST["password"]);
            $userName = test_input($_POST["username"]);
            $password = md5($userPass);

            $logincheck = $conn->prepare("SELECT * FROM users WHERE userName=?");
            $logincheck->bind_param("s", $userName);
            $logincheck->execute();
            $result = $logincheck->get_result();
            $user = $result->fetch_assoc();

            if (!$user) {
                $_SESSION["response"] = "INVALID USERNAME";
            } elseif ($user["userPass"] !== $password) {
                $_SESSION["response"] = "INVALID PASSWORD";
            } else {

            //login is correct, store data into the session and log the session to the DB:

                $_SESSION["idUser"] = $user["idUsers"];
                $_SESSION["response"] = "You have successfully logged in!";
                $_SESSION["session"] = session_id();

                $newsession = $conn->prepare("INSERT INTO sessions (idUser, idSession, startStamp) VALUES (?, ?, ?)");
                $newsession->bind_param("sss", $_SESSION["idUser"], $_SESSION["session"], $timestamp);
                $newsession->execute();

            }
        }


    } elseif (isset($_POST["logout"])) {

        $endsession = $conn->prepare("UPDATE sessions SET lastGalaxy=?, endStamp=? WHERE idSession=?");
        $endsession->bind_param("iss", $_SESSION["idGalaxy"], $timestamp, $_SESSION["session"]);
        $endsession->execute();

        session_unset();
        session_destroy();

    } elseif (isset($_POST["register"])) { /*This handles registration, not relevant*/ }

Когда пользователь не заполняет форму входа правильной информацией о пользователе, сеанс получает значение $ _SESSION ["response"], которое отображается в отображаемой форме входа в систему.

1 Ответ

0 голосов
/ 05 мая 2020

Я нашел решение моей проблемы ... У меня может быть PHP обработчик, просто возвращающий json назад. Таким образом, я могу избежать всей проблемы синхронизации, поскольку сценарий jQuery выполняет свое следующее действие только после получения ответа от обработчика PHP.

Оператор AJAX теперь выглядит следующим образом:

$.post("/backend/validateUser.php", formData, function(data) {
  switch(data.result) {
  //case for each possible result from the handler (login/logout/timeout/register)
  }, "json")

Обработчик PHP просто выводит крошечный фрагмент JSON, когда он успешно завершает все действия в определенном процессе:

echo json_encode(["result"=>"login"]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...