为什么我的登录会话跨越同一服务器上的所有已登录设备

问题描述

在我的登录脚本上,如果像User A这样的用户从其他任何设备登录后,从任何位置登录用户B都获得了用户A的所有会话数据(用户B的登录页面显示用户A的登录名)。我创建一个会话令牌,并使用用户名将其保存在数据库中。另外,还要为每个用户创建一个用户ID并将其保存在数据库中。我无法理解我的会话数据如何通过另一个设备。在测试中,我为print_r($_SESSION);创建的会话数据页面创建了页面,该页面在两个设备上也显示了相同的数据。我无法在脚本中找到解决方案。有谁能帮助我。这是我的脚本。

login.PHP

<form id="loginform" role="form" action="logprocess.PHP" method="POST">
<input id="login-username" type="text" name="user" value="" placeholder="username">
<input id="login-password" type="password" name="pass" placeholder="password" value="">
<input type="hidden" name="token" value="<?PHP echo $_SESSION['token']; ?>">
<input id="login-remember" type="checkBox" name="remember" <?PHP if($value("remember") != ""){ echo "checked"; } ?>> Remember me
<input type="submit" value="Login" id="loginhere">

logprocess.PHP

include_once("session.PHP");
global $session;
if ($_SESSION['token']==$_POST['token']) {
   $login = $session->login($_POST['user'],$_POST['pass'],isset($_POST['remember']));
   header("Location:".$session->referrer);
}

session.PHP

require_once("database.PHP");
class Session
   {
   var $id;
   var $username;
   var $uid;
   var $logged_in;
   function Session(){
       $this->startSession();
       $this->time = time();
   }
   function startSession(){
       global $database;
       session_start();
       $this->logged_in = $this->checkLogin();
       if(!$this->logged_in){
           $database->addGuest($_SESSION['uid'],$this->time);
       } else{
           if($_SESSION['username'] != ''){
           $database->addUser($_SESSION['username'],$this->time);
       } else {return false;}
   }
   if (empty($_SESSION['token'])) {
       if (function_exists('mcrypt_create_iv')) {
           $_SESSION['token'] = bin2hex(mcrypt_create_iv(32,MCRYPT_DEV_URANDOM));
       } else {
           $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32));
       }
   }
  $token = $_SESSION['token'];

  function checkLogin(){
      global $database;

      /* Check if user has been remembered */
      if(isset($_COOKIE['cookname']) && isset($_COOKIE['cookid'])){
         $this->username = $_SESSION['username'] = $_COOKIE['cookname'];
         $this->uid   = $_SESSION['uid']   = $_COOKIE['cookid'];
      }

     /* Username and userid have been set and not guest */
     if(isset($_SESSION['username']) && isset($_SESSION['token']) && isset($_SESSION['uid']) &&
     $_SESSION['username'] != "guest"){ 
     /* Confirm that username and userid are valid */
     if($database->confirmUserID($_SESSION['username'],$_SESSION['uid']) != 0 && $database->confirmUserToken($_SESSION['token'],$_SESSION['username']) != 0){
        /* Variables are incorrect,user not logged in */
        unset($_SESSION['username']);
        unset($_SESSION['uid']);
        unset($_SESSION['token']);
        session_destroy();
        return false;
      }

      /* User is logged in,set class variables */
      $this->userinfo = $database->getUserInfo($_SESSION['username']);
      $this->id = $this->userinfo['id'];
      $this->username = $this->userinfo['username'];
      $this->uid = $this->userinfo['uid'];
      $this->email = $this->userinfo['email'];
      return true;
      } else { return false; }
   }

   function login($user,$pass,$remember){
      $result = $database->confirmUserPass($user,$pass);
      if($result == 1){
          return false;
      } 
      $this->uid = $_SESSION['uid'] = $this->generaterandID(32);
      $database->updateUserField($user,"uid",$this->uid);
      $database->updatetoken($user,$_SESSION['token']);
      if($remember){
         setcookie("cookname",$user,time()+60*60*24*3,"/");
         setcookie("cookid",$this->uid,"/");
      }
   return true;
   }

$session = new Session;
}

anypage.PHP

include_once("session.PHP");
if($session->logged_in){
   /*Do anything*/
}

解决方法

所有用户会话的会话令牌都必须不同,以便分别标识每个用户和每个设备。

我建议对唯一令牌使用UUID。

UUID-通用唯一标识符是一个128位数字,用于标识计算机系统中的信息。