问题描述
在我的登录脚本上,如果像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位数字,用于标识计算机系统中的信息。