在很多時候,我們都要對某些Web 頁面進行安全保護。典型的例子就是前台浏覽頁面與後台管理頁面的安全性。這也是 WEB 上用得最多的一種頁面安全模式。在用PHP4 開發一個小型的書籍管理系統中,我也遇到了這個安全問題。於是我想到了PHP4 的新特性----Session ..
要求目的:同一站點,無權用戶,一般授權用戶和超級用戶能看到和使用不同的頁面。
實現辦法:在要保護的頁面 include 不同級別的安全檢驗摸板。
注意事項:
1 > 要避免用戶浏覽器不使用 cookie 而不能浏覽受保護的頁面(session 默認使用客戶端的 cookie).
2 > 要防止權限被盜用。( PHP 4 的 session 的默認存活期間是從建立 session 開始到關閉浏覽器為止。)
如何使用:
1 > 在需要一般保護的頁面的代碼最前邊加上 include ("secturity2.php"); 就行了
2 > 在需要特殊保護的頁面的代碼最前邊加上 include ("secturity1.php"); 和 include ("secturity2.php"); 就行了
(假設所有文件都在同一個文件夾裡)
程序代碼及詳細解釋:
security1.php 特殊用戶頁面保護摸板
security2.php 一般用戶頁面保護摸板
login2.php 用戶登陸頁面
我們先來看 login2.php (用戶登陸頁面)的代碼:
<?php
session_register("user");#增加用戶名變數
session_register("password"); #增加密碼變數
session_register("tmLast"); #增加時間變數
if($user==""){#判斷是否是第一次登陸
$error="Chooseyounameandinputthepasswordplease!";
}
$tmLast=date("U"); #記錄登陸時間
if($user1)
$user=trim($user1); #記錄用戶名(引用user1變量是為什麼?請讀者自己思考。)
$password=trim($password1); #記錄密碼
if($user1&&$password1){
if($password1==888){ #判斷登陸密碼是否是默認密碼888結束 PHP 程式
$sid="PHPSESSID=".session_id(); #保存當前session的ID號
$warning="Yourpasswordisstillthedefaultpassword888,pleasechangeit.";
header("Location:changePassword.php?$sid&warning=$warning"); #傳遞警告參數warning到changePassword.php 頁面
exit(); #立刻結束 PHP 程式
}
if(strtolower($user)=="root"){ #判斷登陸用戶是否是超級用戶,可以自行擴充用戶
$fileName="backend_index.php";
}
else{
if(!$fileName) #判斷進入登陸頁面的上一頁是否是受保護頁面
$fileName="index.php";
}
$sid="PHPSESSID=".session_id(); #保存當前session的ID號
header("Location:$fileName?$sid); #登陸成功進入指定頁面,傳遞當前session的ID號,防止用戶不使用 cookie 而讀不到 session 值
exit(); #立刻結束 PHP 程式
}
?>
<html>
<title></title>
<head>
<linkrel="stylesheet"href="class/style.css">
<metahttp-equiv="Content-Type"content="text/html;charset=gb2312">
</head>
<h2>LoginPage</h2>
<?php
echo"$error"; #顯示登陸提示
?>
<formaction="<?phpecho$PHP_SELF;#提交到當前頁?>"method=post>
<P><b>Name:</b>
<?php
include("class/dbclass.inc"); #調用dbclass.inc類,用法和 mysql.inc 類一樣
$q=newDB_Sql; #定義一個新的對象
$q->connect($Host,$Database,$User,$Password); #連接 mysql數據庫
$query="selectchrUserName,chrFirstName,chrLastName".
"fromUser".
"wherechrFirstName!=''".
"orderbychrFirstName";
$q->query($query); #執行sql語句
echo"<selectname=user1size=1>";
while($q->next_record()){ #從數據庫中調出一般用戶
if($user==$q->f(0)) #判斷是否是當前用戶
$select="selected"; #是當前用戶則設置為默認值
else
$select="";
echo"<optionvalue='".$q->f(0)."'$select>".
ucfirst($q->f(1))."". #用戶名首字大寫
ucfirst($q->f(2))."</option>";
}
echo"</select>";
?></P>
<P><b>Password:</b><INPUTname=password1type=password></P>
<INPUTname=tmLasttype=hiddenvalue=<?phpechodate("U")?>>
<INPUTname=fileNametype=hiddenvalue=<?phpecho$fileName?>>
<P><INPUTname=submittype=submitvalue=確認></P>
</form>
security2.php (一般用戶頁面保護摸板):
<?php
session_register("user"); #說明同上
session_register("password");
session_register("tmLast");
if($fileName=="")
$fileName=$PHP_SELF; #記錄當前頁面路徑
if($durtime=="")
$durtime=300; #設置 session “失效”時間
$currtime=date("U");
if(($currtime-$tmLast)>$durtime){ #判斷 session是否“失效”
//session_destroy();
$error=urlencode("Seesionexpired.Loginagainplease!");
header("Location:login2.php?fileName=$fileName&error=$error&user=$user"); #跳到重新登陸頁
exit();
}
else{
$tmLast=$currtime; # session 沒“失效”則更新最後“登陸”時間
}
include("class/dbclass.inc");
$q=newDB_Sql;
$q->connect($Host,$Database,$User,$Password);
$query="selectidUserfromUser".
"wherechrUserName='$user'".
"andchrPasswd='$password'";
$q->query($query);
if(!$q->num_rows()){ #判斷是否找到密碼匹配的用戶
$error=urlencode("PasswordiswrongorNoprivilegeuser.");
header("Location:login2.php?fileName=$fileName&error=$error&user=$user"); #跳到密碼錯誤登陸頁
}
else{
$sid="PHPSESSID=".session_id();
$q->next_record();
$USERID=$q->f(idUser); #保存通過驗證用戶的ID號,方便以後使用
}
?>
security1.php (特殊用戶頁面保護摸板):
<?php
session_register("user"); #說明同上
$privilege="root,macro,jackie"; #設置超級用戶名單列表,用“,”隔開
$pieces=explode(",",$privilege); #取得單個超級用戶名單
for($i=0;$i<count($pieces);$i++){
if(strtolower($user)==$pieces[$i]){ #判斷是否是超級用戶
$hasPrivilege=1;
break; #跳出判斷循環
}
}
if(!$hasPrivilege){
if($fileName=="")
$fileName=$PHP_SELF;
$error=urlencode("Youhavenoprivilegetoviewthispage!");
header("Location:login2.php?fileName=$fileName&error=$error&id=$id");
exit(); #跳到無權用戶登陸頁面
}
?>
上述程序由 Macro Zeng保留完整解釋權。