2016-06-09 127 views
0

我知道有很多關於此主題的帖子,但他們都沒有解決我的問題。PHP會話不會在頁面更改中保留價值

我有我的Windows計算機上運行的WAMP服務器。我創建了一個登錄系統,可以設置PHP會話並驗證他們在創建頁面時是否正在工作。一旦我改變到不同的頁面,無論是通過輸入URL或JavaScript函數,我失去了會話。

這裏是我的test.php的是登錄

require_once('config.php'); 

    $user = new User(); 
    $result = $user->login('[email protected]', 'mysecretpassword'); 
    echo $result; 
    echo '</br>'; 
    $result = $user->isLoggedIn(); 
    echo $result; 

該用戶是實際登錄

public function login($email, $password) { 

    // Hash Password 
    $password = $this->hashPassword($password); 

    // Check if email and password match 
    $query = "SELECT id, confirm_email FROM users WHERE email = ? AND password = ?"; 

    $a_bind_params = array($email, $password); 
    $a_param_types = array('s','s'); 
    $results = $this->db->select($query, $a_bind_params, $a_param_types); 

    // If we didnt get a result then email/password must be wrong 
    if(count($results) == 0) return 1; 

    // Now check that they verrified their email 
    if($results[0]['confirm_email'] == 'N') return 2; 

    // User is real and everything is good 

    // Update login Date 
    $a_bind_params = array(date('Y-m-d H:i:s'), $results[0]['id']); 
    $a_param_types = array('s','s'); 
    $query = "UPDATE users SET login_at = ? WHERE id = ?"; 

    // There was a problem updating their login table so just fail the login 
    if(!$this->db->update($query, $a_bind_params, $a_param_types)) return 3; 

    // Login user 
    Session::set("user_id", $results[0]['id']); 
    session_regenerate_id(true); 
    Session::set("login_fingerprint", $this->_generateLoginString()); 

    return 0; 
} 

這裏,用戶的功能來檢查,如果用戶登錄功能in

// Checks if user is logged in 
    public function isLoggedIn() { 
     //if $_SESSION['user_id'] is not set return false 
     if(Session::get("user_id") == null) 
      return false; 

     $loginString = $this->_generateLoginString(); 
     $currentString = Session::get("login_fingerprint"); 
     if($currentString != null && $currentString == $loginString) 
      return true; 
     else { 
     //destroy session, it is probably stolen by someone 
     $this->logout(); 
     return false; 
     } 
    } 

這裏是創建會話的會話函數

public static function startSession() { 
     ini_set('session.use_only_cookies', true); 

     $cookieParams = session_get_cookie_params(); 
     session_set_cookie_params(
      $cookieParams["lifetime"], 
      $cookieParams["path"], 
      $cookieParams["domain"], 
      SESSION_SECURE, 
      SESSION_HTTP_ONLY 
     ); 

     session_start(); 
     session_regenerate_id(true); 
    } 

這些都是設定的功能/獲取用戶會話

public static function set($key, $value) { 
     $_SESSION[$key] = $value; 
    } 

    public static function get($key, $default = null) { 
     if(isset($_SESSION[$key])) 
      return $_SESSION[$key]; 
     else 
      return $default; 
    } 

最後,這是實際調用session_start(),包括一些常量我的config.php文件

// REQUIRE ALL FILES 
require_once("ClassSession.php"); 
require_once("ClassDatabase.php"); 
require_once("ClassUser.php"); 
Session::startSession(); 

如果我瀏覽到另一頁叫做test.php

include "config.php"; 
$user = new User(); 
if($user->isLoggedIn()) echo 'logged in'; 
else 'Not logged in'; 

會話丟失,用戶不再登錄。

我已經在PHP.ini中檢查了我的sessions.save_path並檢查了wamp64/temp文件夾,並且我的會話正在存儲在那裏。我也在每個頁面上調用session_start(),因爲我在兩個測試頁面都包含了config.php。不知道爲什麼我失去了我的會議。

編輯

我忘了說什麼是真正發生的事情。當我登錄用戶時,我從數據庫中查找他們的user_id並將其存儲到$_SESSION['user_id']中。當我從登錄用戶的頁面訪問$ _SESSION [user_id]時,我找回了正確的值。但是,當我更改爲另一頁$_SESSION['user_id']爲空。

UPDATE

session_regenerate_id(true)是沒有問題的。

這裏是打印php_info()時,我的會話設置 enter image description here

+0

請用[mcve] –

+0

更改這一串代碼可能會錯過'session_start()'調用。 –

+0

我不知道我怎麼可能使它變小。所有這些都是必需的。如果你想閱讀我的整篇文章,你會發現我在每一頁上調用'session_start()'。 –

回答

3
session_set_cookie_params(
     $cookieParams["lifetime"], 
     $cookieParams["path"], 
     $cookieParams["domain"], 
     SESSION_SECURE, 
     SESSION_HTTP_ONLY 
    ); 

檢查值在這裏。什麼是SESSION_SECURE常量值?也許你只是將​​cookie的使用限制在https上,而你的網站是http。

+0

我必須等待11小時獎勵賞金。但是這已經解決了我的問題。感謝您閱讀我的文章並發現問題。 –

0

你的問題可能是

session_regenerate_id(true); 

這將刪除您的會話,並用一個新的會話ID更新它,你會失去與舊會話ID的任何會話數據的關聯。

從參數的文檔到這個函數。

delete_old_session

是否刪除舊的相關會議文件或沒有。

+0

[session_regenerate_id](http://php.net/manual/en/function.session-regenerate-id.php)在描述中,它聲明_「session_regenerate_id()將用新的替代當前會話ID,並保持當前會話信息「。_會話信息不會丟失。 –

+0

是的,但您使用'delete_old_session = true'來刪除舊的會話數據。 – phreakv6

+0

是刪除舊會話數據。數據已被傳輸到新的會話文件。 –

0

你說config.php調用session_start();但是我看到你正在使用 ini_set(use.cookie,true)

這是錯誤的,並導致您的問題。

+0

這是怎麼回事,導致我的錯誤? [此鏈接](http://stackoverflow.com/questions/3517350/session-hijacking-and-php)指出,使用'ini_set('session.use_only_cookies',1);'建議 –

1

我剛剛寫了一個非常基本的PHP代碼,讓你知道如何快速構建它。您應該更改參數,使用mysqli或PDO或ORM(無論你喜歡什麼),但基本思想保持不變。使用安全cookie,遵循最佳實踐來隱藏需要保護的內容。

創建一個PHP文件調用它functions.php並粘貼到它

<?php 

    session_start(); 

function createsessions($email, $password, $loginId) 
{ 
    //Add additional member to Session array as per requirement 
    //session_register(); 

    $_SESSION["email"] = $email; 
    $_SESSION["password"] = $password; 
    $_SESSION["loginId"] = $loginId; 

    //Add additional member to cookie array as per requirement 
    setcookie("loginEmail", $_SESSION['loginEmail'], time() + 31536000, "/", ".example.com", 0, true); 
    setcookie("password", $_SESSION['password'], time() + 31536000, "/", ".example.com", 0, true); 
    setcookie("loginId", $_SESSION['loginId'], time() + 31536000, "/", ".example.com", 0, true); 


} 

#Authenticate User 
function confirmUser($email_address, $password) 
{ 

    if (mysql_num_rows(mysql_query("select * from TABLE where email ='" . $email_address . "' and password =MD5('" . $password . "')"))) { 
     $loginstatus = 1; //account exists, login 
     return $loginstatus; 
    } else { 
     $loginstatus = 0; // Incorrect Credentials 
     return $loginstatus; 
    } 
} 


#Function to check login status 
function checkLoggedin() 
{ 
    if (isset($_SESSION['email']) && isset($_SESSION['password'])) 
     return true; 
    elseif (isset($_COOKIE['email']) && isset($_COOKIE['password'])) { 
     if (confirmUser($_COOKIE['email'], $_COOKIE['password'])) { 
      $sql_id = mysql_query("select id, email, password from TABLE where email ='" . $_COOKIE['email'] . "' and password ='" . $_COOKIE['password'] . "'"); 
      $sql_array = mysql_fetch_row($sql_id); 

      #Register Session & Cookies Variables 
      $loginId = $sql_array[0]; 
      $email = $sql_array[1]; 
      $password = $sql_array[2]; 

      //Clear all sessions and cookies first 
      clearsessionscookies(); 

      createsessions($email, $password, $loginId); 

      return true; 
     } else { 

      clearsessionscookies(); 
      return false; 
     } 
    } else 
     return false; 
} 


#Logout and clear session and cookies data 
function clearsessionscookies() 
{ 
    unset($_SESSION['email']); 
    unset($_SESSION['password']); 
    unset($_SESSION['loginId']); 


    setcookie("PHPSESSID", null, time() - 31536000, "/", ".example.com", 0); 
    setcookie("email", null, time() - 31536000, "/", ".example.com", 0); 
    setcookie("password", null, time() - 31536000, "/", ".example.com", 0); 
    setcookie("loginId", null, time() - 31536000, "/", ".example.com", 0); 

    session_unset(); 
    session_destroy(); 
    ob_end_flush(); 

} 
?> 

createsessions()clearsessionscookies()有助於處理會話創建和刪除下面的代碼。將example.com替換爲您的Cookie域。

從你的HTML頁面,使一個AJAX調用的函數,並把下面的代碼在它

<?php 
#AJAX Call to this function 
function checkLogin() 
{ 

    // Don't forget to protect against MySQL injection 
    $user_email = mysql_real_escape_string($_POST['emailaddress']); 
    $password = mysql_real_escape_string($_POST['password']); 

    if ($user_email == '' || $password == '') { 
     echo "Invalid email address or password. Please try again."; 
     $hasError = true; 
    } 

    $loginstatus = confirmUser($user_email, $password); 

    if ($loginstatus == 0) { 
     echo "Invalid ID or password. Please try again."; 
     $hasError = true; 
    } else // Login Now 
    { 
     if ($hasError != true) { 

      #Get User Details In Session 
      $sql_id = mysql_query("select loginId, email, password from TABLE where email ='" . $user_email . "' and password =MD5('" . $password . "')"); 
      $sql_array = mysql_fetch_row($sql_id); 


      #Register Session & Cookies Variables 
      $loginId = $sql_array[0]; 
      $email = $sql_array[1]; 
      $password = $sql_array[2]; 


      //Create Fresh sessions and cookies 
      createsessions($email, $password, $loginId); 

      //Redirect to Dashboard or wherever you want the customer to go post authentication 
     } 
    } 
} 

?> 

我特意保留了登錄ID,因此您可以專門處理特定的記錄與其他表引用您可能與用戶表關聯。

我希望這會起作用,並幫助您保持用戶在cookie中的指定時間內登錄。