簡體   English   中英

為什么頁面多次加載時會破壞PHP會話?

[英]why the PHP session is destroyed when page is loading multiple time?

我有使用php登錄和注銷功能的網站。

因此,對於登錄,首先我調用以下函數:

function sec_session_start() {
    $session_name = 'happiechef_session_ids';   // Set a custom session name
    $secure = false;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location:index");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"], 
        $cookieParams["domain"], 
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);
    session_start();            // Start the PHP session 
    session_regenerate_id(true);    // regenerated the session, delete the old one. 
}

然后我調用以下函數來檢查mysql數據庫中的用戶登錄信息:

function admin_login($email, $pass) {
    global $conn;   

    $query = mysqli_query($conn, "SELECT a_email, a_pass, a_id FROM admin_profile WHERE a_email = '$email' LIMIT 1");
    $query_result =  mysqli_fetch_array($query);
    $a_id = (int) $query_result['a_id']; 
    $db_hash = htmlspecialchars($query_result['a_pass']);
    $num = mysqli_num_rows($query);

    if($num == 1) {
        if (checkbrute($email) == true) {
        // if true account is locked
            return false;
        } else {
            if(verify($pass, $db_hash)) {
                $a_id = preg_replace("/[^0-9]+/", "", $a_id);
                $email = validate_data($email);
                $user_browser = $_SERVER['HTTP_USER_AGENT'];
                $_SESSION['logged_admin_user'] = $email;
                $_SESSION['logged_admin_id'] = $a_id;                
                $_SESSION['login_string'] = hash('sha512', $db_hash . $user_browser);
                return true;
            } else {
                $time = time();
                $query =  mysqli_query($conn, "INSERT INTO login_attempt VALUES('', '$email', '$time')");
                return false;
            }
        }
    } else {
        return false;
    }    
}

好吧,當我使用鍵盤上的F5 key多次刷新頁面時,它會自動注銷,而有時在我訪問其他頁面時,它要求我登錄! 不知何故,它破壞了PHP會話。

誰能告訴我代碼中的問題是什么?

提前致謝。

更新:

這是檢查用戶是否已登錄的功能:

function admin_login_check() {
    // Check if all session variables are set 
    if (isset($_SESSION['logged_admin_user'], $_SESSION['logged_admin_id'], $_SESSION['login_string'])) {
        global $conn;
        $user_id = $_SESSION['logged_admin_id'];
        $login_string = $_SESSION['login_string'];
        $username = $_SESSION['logged_admin_user'];

        // Get the user-agent string of the user.
        $user_browser = $_SERVER['HTTP_USER_AGENT'];

        if($query = mysqli_query($conn, "SELECT a_pass FROM admin_profile WHERE a_email = '$username' ")) {
            $num =  mysqli_num_rows($query);
            if($num == 1) {

                $result =  mysqli_fetch_array($query);
                $password = htmlspecialchars($result['a_pass']);

                // if hash equals function is not exist    
                if(!function_exists('hash_equals')){
                    function hash_equals($str1, $str2){
                        if(strlen($str1) != strlen($str2)){
                            return false;
                        } else {
                            $res = $str1 ^ $str2;
                            $ret = 0;
                            for($i = strlen($res) - 1; $i >= 0; $i--) {
                                $ret |= ord($res[$i]);
                            }
                            return !$ret;
                        }
                    }
                }
                $login_check = hash('sha512', $password.$user_browser); 
                if (hash_equals($login_check, $login_string) ){                    
                    return true;
                } else {          
                    return false;
                }
            } else {
                 return false;
            }
        } else {
           return false;
        }
    } else {        
        return false;
    } 
}

如果刪除session_regenerate_id(true)該會話不應再被破壞。

為什么會這樣呢?
session_regenerate_id()用新的會話ID替換當前的會話ID。 會話信息將被保留。 當您經常使用此功能(重新加載,AJAX等)時,可以在會話中看到這種效果。 PHP僅對一個正在運行的任務具有訪問會話的限制。 如果您運行session_regenerate_id()經常/快速地使任務進入隊列。 因此,正在發生以下情況:

  1. 第一次調用將更改會話ID並刪除舊會話(如果parameter為true )。
  2. 第二個呼叫仍然具有舊的會話ID,並嘗試對其進行一些操作。
  3. 由於舊會話不再存在,因此將創建一個新會話。 用戶現在已注銷(會話現在無效)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM