為了在保證該系統安全的同時,不會加重我現有數據庫的負擔。因此這個新的系統要依賴cookies.這確實是一個兩難的選擇,因為如果只是設置一個用戶名的cookie,是很不安全的,這行不通,但從數據庫的負擔考慮,我也不能加入一個簡單的無序碼而交由我的數據庫來進行驗證。
解決的方法是同時設置兩個cookie,一個是用戶名的cookie,一個是無序碼的cookie. 這個無序碼實際上是由用戶名和一個超級密碼(只有程序設計者知道)組合通過md5 ()函數運算產生的。由于md5 ()是一個單向的無序碼,因此是不可以破解的。在用戶更改email 時,我也可以用該email 和超級密碼產生一個無序碼,以讓用戶確認修改。這實際上是一個公匙/ 私匙類的系統。不明白?不要緊,下面再慢慢說明。
有趣的是,這個系統的擴展能力是可以達到無窮的,因為該系統的主要工作是計算md5 ()函數的值,而且由web 服務器完成,在負載增加時,可以加入其它的服務器來分擔負載,雖然認證系統不會拖跨一個數據庫,但是這樣做就讓最終的瓶頸只能出現在數據庫上。
以下是該庫中的兩個函數——記號產生和記號認證函數。
<?php
$hidden_hash_var='your_secret_password_here';
$LOGGED_IN=false;
unset($LOGGED_IN);
function user_isloggedin() {
global $user_name,$id_hash,$hidden_hash_var,$LOGGED_IN;
file://已經進行無序碼的檢測了嗎
file://如果是的話,返回該變量
if ( isset($LOGGED_IN) ) {
return $LOGGED_IN;
}
file://are both cookies present?
if ($user_name && $id_hash) {
/*
由cookies中得來的用戶名和系統超級密碼產生一個認證用的無序碼如果該無序碼與cookie中的無序碼一樣,則cookies中的變量是可信的,用戶已經登錄
*/
$hash=md5($user_name.$hidden_hash_var);
if ($hash == $id_hash) {
file://無序碼符合,設置一個全局變量,這樣我們在再次調用該函數的時候,
file://就無需再次進行md5()運算
$LOGGED_IN=true;
return true;
} else {
file://兩個無序碼不符合,沒有登錄
$LOGGED_IN=false;
return false;
}
} else {
$LOGGED_IN=false;
return false;
}
}
function user_set_tokens($user_name_in) {
/*
一旦用戶名和密碼通過驗證,就調用這個函數
*/
global $hidden_hash_var,$user_name,$id_hash;
if (!$user_name_in) {
$feedback .= ' ERROR - User Name Missing When Setting Tokens ';
return false;
}
$user_name=strtolower($user_name_in);
file://使用用戶名和超級密碼創建一個無序碼,作判斷是否已經登錄用
$id_hash= md5($user_name.$hidden_hash_var);
file://設置cookies的有效期為一個月,可設置為任何的值
setcookie('user_name',$user_name,(time()+2592000),'/','',0);
setcookie('id_hash',$id_hash,(time()+2592000),'/','',0);
}
?>