PHP会话未在页面更改

时间:2016-06-09 04:37:29

标签: php session

我知道有很多关于这个主题的帖子,但没有一个帖子解决了我的问题。

我的Windows计算机上运行了WAMP服务器。我创建了一个登录系统,它能够设置PHP会话并验证它们在创建它们的页面上是否正常工作。一旦我更改为其他页面,通过键入URL或javascript函数我会丢失会话。

这是我的test.php,用于记录用户

  require_once('config.php');

  $user = new User();
  $result = $user->login('email@gmail.com', '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;
}

以下是检查用户是否已登录的功能

  // 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;
  }

最后这是我的config.php文件,它实际上调用session_start()并包含一些常量

// 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']为空时。

更新

session_regenerate_id(true)不是问题。

这是打印php_info()时的会话设置 enter image description here

4 个答案:

答案 0 :(得分:4)

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

在此检查值。什么是SESSION_SECURE const值?也许您将cookie使用限制为仅限https,并且您的网站位于http。

答案 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
        }
    }
}

?>

我故意保留了LoginID,因此您可以专门处理特定记录,以便与您可能与用户表关联的其他表进行引用。

我希望这会有效并帮助您让用户在Cookie中保持指定时间段。

答案 2 :(得分:0)

你的问题可能是

session_regenerate_id(true);

这将删除您的会话并使用新的会话ID更新它,并且您将失去与旧会话ID的任何会话数据的关联。

从参数的文档到此函数。

  

<强> delete_old_session

     

是否删除旧的关联会话文件。

答案 3 :(得分:0)

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

这是错误的并导致你的问题。