我編碼了我的第一個會話系統。問題如下。有關會議的幾個問題
// INDEX.PHP
include("db.php"); // this file starts session with session_start(); also changes the default session name
if($_POST['login']){ $login = escape($_POST['login']); }
if($_POST['password']){ $password = escape($_POST['password']); }
if(isset($login) && isset($password)){ // LOGIN ATTEMPT
// check for brute force attacks
$btime = $time-600; // 10 minutes
$pull = $DB->query("SELECT * FROM logins WHERE user='$login' AND time>$btime");
if($DB->num_rows($pull) > 5){ // more than 10 tries in the last 10 minutes
$error = "Too many login attempts have been made with this login. ";
// maybe lock the account for x hours
}else{
// AUTHENTICATE
$sql = $DB->query("SELECT * FROM users WHERE user='$login' AND password='$password'");
if($DB->n
um_rows($sql) == 1){ // AUTHENTICATED
$user = $DB->fetch_array($sql);
$ok = 1;
session_regenerate_id();
$_SESSION['userid'] = $user['id'];
$_SESSION['agent'] = md5($_SERVER['HTTP_USER_AGENT']);
$_SESSION['idle'] = $time;
header("Location: welcome.php"); // REDIRECT TO USER AREA
}else{ // NOT AUTHENTICATED
$ok = 0;
$error = "Wrong pass or login.";
}
// log all attempts (removed)
}
}
功能,檢查會話:
function checksession(){
global $DB, $time;
if($_SESSION['userid'] > 0){
$userid = intval($_SESSION['userid']);
$user = $DB->fetch("SELECT * FROM users WHERE id=$userid");
$idle = $time-$_SESSION['idle'];
if(!$user){ header("Location: index.php"); }
elseif($_SESSION['agent'] != md5($_SERVER['HTTP_USER_AGENT'])){ session_destroy(); header("Location: ".$site."index.php"); } // check user agent
elseif($idle > 7200){ session_destroy(); header("Location: ".$site."index.php"); } // destroy session if no activity for 2 hours
else{
$_SESSION['idle'] = $time;
}
}else{ header("Location: ".$site."index.php"); // user id not set
}
return $userid;
}
註銷功能
function logout(){
session_destroy();
header("Location: index.php");
}
它工作正常,但它並不完美。
問題:
當我做session_regenerate_id();會話ID發生變化,但舊會話仍保持活動狀態。所以這非常沒用。我在安全級別發生變化時執行此操作。我也考慮過定期做。我正在使用PHP 5.3.6的MAMP。
如果用戶不想破壞會話並簡單地關閉瀏覽器,會話文件似乎永遠留在系統中。我想知道如何1)使會話在X小時後死亡,即使用戶處於活動狀態。 2)如果用戶閒置會使會話死掉(有點像我現在擁有的系統,但是來自系統的一方)。
我注意到,如果我在修改會話cookie之前登錄相同的會話文件,除了使用用戶信息的新重新生成的id以外,還會保存在會話文件文件夾(空)中。不知道這個,只是覺得很奇怪。
我是否正確銷燬會話?
該網站應該有一個相當高的安全等級,因爲真錢會涉及到用戶帳戶。我正考慮在會話中保存頁面點擊次數,如果發生更改,則意味着其他人已將會話結束。會議然後將被殺死。
沒有session_regenerate_id():用戶可以提交他自己的會話。在其他問題上陷入困境。我選擇了用戶代理而不是IP,因爲IP可以更改。 – domino
「我注意到,如果我修改會話cookie之前登錄相同的會話文件獲取保存在會話文件文件夾(空)除了新的重新編號與用戶信息」 - 我的意思是,如果我編輯PHPSESSION cookie然後登錄,會話文件與用戶提交的名字保存在會話文件夾中。這是空的。 – domino
即使您重新生成,用戶也將始終能夠提交自己的會話。再生只是給他們一個新的會話ID - 如果他們真的是惡意的,他們會忽略它,並繼續與任意會話ID聯繫。確保會話ID匹配客戶端的某個唯一標識符是您的工作。我認爲IP地址比用戶代理更好,但IP地址將受到MITM攻擊,除非您通過SSL。 – jedwards