Php 为什么浏览器关闭时我的cookie没有过期?
我编写了一个类,它将帮助我完成应用程序身份验证过程 我们的想法是Php 为什么浏览器关闭时我的cookie没有过期?,php,security,session,session-cookies,Php,Security,Session,Session Cookies,我编写了一个类,它将帮助我完成应用程序身份验证过程 我们的想法是 将会话存储引擎从服务器上的文件更改为 数据库 创建一个随机会话id,不要在PHP上中继到 为我生成会话id 更改会话的长度 id设置为允许的最大值(即40个字符) 将新会话id与用户id(应用程序用户标识符,)以及用户的IP地址和用户代理信息一起存储到表中 设置空闲超时,以便系统自动销毁用户 1800秒空闲时间后的会话 在实现上述功能后,在每个请求的页面上,我检查以下内容是否正确 用户浏览器中的有效会话ID 确保我可以将当前IP地
<?php
ini_set('session.hash_function', 1);
ini_set('session.hash_bits_per_character', 4);
class sessionManager {
private $db;
private $user_id;
private $user_ip;
private $user_agent;
private $autherizedUser = false;
private $cookie_name;
private $current_session_id;
private $max_session_idle_time = 1800;
private $current_time;
public function __construct($name, $user_id = NULL, $limit = 0, $path = '/', $domain = null, $secure = null){
// Set the cookie name
session_name($name);
// pass the current user_id. This is only useful at the time of login "to start a new session"
$this->user_id = $user_id;
//assign the cookie name that will be used for the session
$this->cookie_name = $name;
$this->current_time = time();
if(isset($_SERVER['REMOTE_ADDR']))
$this->user_ip = $_SERVER['REMOTE_ADDR'];
if(isset($_SERVER['HTTP_USER_AGENT']))
$this->user_agent = $_SERVER['HTTP_USER_AGENT'];
// Set SSL level
$https = isset($secure) ? $secure : isset($_SERVER['HTTPS']);
//set the session storage to point custom method
session_set_save_handler(
array($this, "open"),
array($this, "close"),
array($this, "read"),
array($this, "write"),
array($this, "delete"),
array($this, "garbageCollector")
);
//Set session cookie options
session_set_cookie_params($limit, $path, $domain, $https, true);
//set the current session_id that is stored in the cookie
if(!empty($this->cookie_name) && isset($_COOKIE[$this->cookie_name]) && !empty($_COOKIE[$this->cookie_name]))
$this->current_session_id = $_COOKIE[$this->cookie_name];
//if there is no IP detected - make it invalid
if( empty($this->user_ip) || empty($this->user_agent) ){
echo 'Invalid Request!!!';
exit();
}
//start session
if(session_id() == '')
session_start();
// Make sure the session hasn't expired, and destroy it if it has
if( $this->isValidSession() ){
if($this->isHijacking()){
//destroy the session
$this->destroy();
} else {
//re-set the idle timeout
$_SESSION['MA_IDLE_TIMEOUT'] = $this->current_time + $this->max_session_idle_time;
$this->autherizedUser = true;
}
} else {
//make sure there is a user_id passed before creating a new session
if( !empty($this->user_id) ){
//destroy the session
$this->destroy();
//start a new session
$new_session_id = $this->generateSessionID();
session_id($new_session_id);
session_start();
$this->setSessionValues();
$this->autherizedUser = true;
}
}
}
public function destroy(){
$this->autherizedUser = false;
session_unset();
session_destroy();
unset($_COOKIE[SESSION_NAME]);
}
/**
* This function regenerates a new ID and invalidates the old session. This should be called whenever permission
* levels for a user change.
*/
private function setSessionValues(){
$_SESSION = array();
//set the IP address info
$_SESSION['MA_IP_ADDRESS'] = $this->user_ip;
// save the agent information
$_SESSION['MA_USER_AGENT'] = $this->user_agent;
//set the idle timeout
$_SESSION['MA_IDLE_TIMEOUT'] = $this->current_time + $this->max_session_idle_time;
}
//This function is used to see if a session has expired or not.
private function isValidSession(){
if(empty($this->current_session_id) )
return false;
if( !isset($_SESSION['MA_IP_ADDRESS']) || !isset($_SESSION['MA_USER_AGENT']) || !isset($_SESSION['MA_IDLE_TIMEOUT']) )
return false;
if( empty($_SESSION['MA_IP_ADDRESS']) || empty($_SESSION['MA_USER_AGENT']) || empty($_SESSION['MA_IDLE_TIMEOUT']) )
return false;
//if the session expired - make it invalid
if( $_SESSION['MA_IDLE_TIMEOUT'] < $this->current_time )
return false;
//the session is valid
return true;
}
//This function is used to see if a session has expired or not.
private function isHijacking(){
//if the set IP address no not match the current user's IP address value - make it invalid
if( $_SESSION['MA_IP_ADDRESS'] != $this->user_ip )
return true;
//if the set user agent value do not match the current user agent value - make it invalid
if( $_SESSION['MA_USER_AGENT'] != $this->user_agent )
return true;
//the session is valid
return false;
}
public function isAutherized(){
return $this->autherizedUser;
}
private function generateSessionID($len = 40) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-';
$newStr = '';
$maxLen = strlen($characters)-1;
for ($i = 0; $i < $len; ++$i)
$newStr .= $characters[rand(0, $maxLen)];
return $newStr;
}
//open the database connection for the session storage engine
public function open(){
$this->db = new connection();
if($this->db)
return true;
// Return False
return false;
}
//close the database connection for the session storage engine
public function close(){
if($this->db->endConnection())
return true;
// Return False
return false;
}
//read current session variables from the session database
public function read($id){
// Set query
$data = $this->db->getDataSet('SELECT data FROM sessions WHERE session_id = ?', array($id));
if(count($data) == 1)
return $data[0]['data'];
return '';
}
//replace the existing data using the current session id
public function write($id, $data){
// Set query
$replace = $this->db->processQuery('INSERT INTO sessions(session_id, access, data, user_id) VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
session_id = ?,
access = ?,
data = ?', array($id, $this->current_time, $data, $this->user_id, $id, $this->current_time, $data));
if($replace)
return true;
// Return False
return false;
}
//delete a session record from the storage engine
public function delete($id){
// Set query
$delete = $this->db->processQuery('DELETE FROM sessions WHERE session_id = ? OR user_id IS NULL', array($id));
if($delete)
return true;
// Return False
return false;
}
//deletes all expired session - if the access time is less that current time
public function garbageCollector($max){
// Calculate what is to be deemed old
$old = $this->current_time - $max;
// Set query
$delete = $this->db->processQuery('DELETE FROM sessions WHERE access < ?', array($old));
if($delete)
return true;
// Return False
return false;
}
}
?>
然后,我执行以下代码,确保用户经过身份验证
$session = new sessionManager(SESSION_NAME, NULL, SESSION_MAX_AVAILABLE, SESSION_SAVE_PATH, SESSION_SAVE_URL, SESSION_HTTPS_ONLY);
$session_id = $_COOKIE[SESSION_NAME];
$access_time = time();
if( $session->isAutherized() === false || empty($session_id) ){
$session->destroy();
header('Location: '.ABSOLUTE_PATH.'login.php');
exit();
}
. 具体看看哪些浏览器没有使cookie过期,哪些用户设置到位。Jared,我的函数是随机的,它使用a-z a-z、减号和逗号。我被告知内置PHP函数将更容易暴力猜测会话ID。此外,关于我代码中的cookie,我将其设置为0过期,这意味着当broswer关闭时过期。与链接Firefox设置类似的Chrome设置是“继续我离开的地方”@MichaelBerkowski我想你说得有道理。非常感谢。你觉得我们班有什么问题吗?我能做些什么来进一步提高安全性?有一个StackExchange网站供代码审查:
$session = new sessionManager(SESSION_NAME, NULL, SESSION_MAX_AVAILABLE, SESSION_SAVE_PATH, SESSION_SAVE_URL, SESSION_HTTPS_ONLY);
$session_id = $_COOKIE[SESSION_NAME];
$access_time = time();
if( $session->isAutherized() === false || empty($session_id) ){
$session->destroy();
header('Location: '.ABSOLUTE_PATH.'login.php');
exit();
}