典型的前台瀏覽與後台管理分離架構中,需要根據用戶角色(無權訪客、一般授權用戶、超級管理員)動態控制頁面存取權限。PHP 4 引入的 Session 機制為此提供了原生支援。
採用「保護模板」機制:在需保護的頁面頂部引入對應等級的驗證文件:
include('security2.php');include('security1.php'); include('security2.php');login2.php<?php
session_register('user');
session_register('password');
session_register('tmLast');
if ($user == '') {
$error = '請選擇用戶名並輸入密碼!';
}
$tmLast = date('U'); // 記錄登入時間戳
if ($user1) {
$user = trim($user1);
$password = trim($password1);
}
if ($user1 && $password1) {
// 預設密碼 888 強制修改
if ($password1 == '888') {
$sid = 'PHPSESSID=' . session_id();
$warning = '您仍在使用預設密碼 888,請立即修改!';
header("Location: changePassword.php?$sid&warning=$warning");
exit();
}
// 超級用戶判斷
if (strtolower($user) == 'root') {
$fileName = 'backend_index.php';
} else {
if (!$fileName) $fileName = 'index.php';
}
$sid = 'PHPSESSID=' . session_id();
header("Location: $fileName?$sid"); // 傳遞 SID 防 Cookie 失效
exit();
}
?>
<html>
<head>
<title>登入系統</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<h2>登入頁面</h2>
<?php echo $error; ?>
<form action="<?php echo $PHP_SELF; ?>" method="post">
<p><b>用戶名:</b>
<?php
include('class/dbclass.inc');
$q = new DB_Sql;
$q->connect($Host, $Database, $User, $Password);
$query = "SELECT chrUserName, chrFirstName, chrLastName FROM User WHERE chrFirstName != '' ORDER BY chrFirstName";
$q->query($query);
echo "<select name='user1' size='1'>";
while ($q->next_record()) {
$select = ($user == $q->f(0)) ? 'selected' : '';
echo "<option value='{$q->f(0)}' $select>" .
ucfirst($q->f(1)) . ' ' . ucfirst($q->f(2)) . "</option>";
}
echo "</select>";
?></p>
<p><b>密碼:</b><input name="password1" type="password"></p>
<input name="tmLast" type="hidden" value="<?php echo date('U'); ?>">
<input name="fileName" type="hidden" value="<?php echo $fileName; ?>">
<p><input name="submit" type="submit" value="確認"></p>
</form>
</body>
</html>
security2.php<?php
session_register('user');
session_register('password');
session_register('tmLast');
if ($fileName == '') $fileName = $PHP_SELF;
if ($durtime == '') $durtime = 300; // 5 分鐘逾時
$currtime = date('U');
if (($currtime - $tmLast) > $durtime) {
// Session 過期
$error = urlencode('Session 已過期,請重新登入!');
header("Location: login2.php?fileName=$fileName&error=$error&user=$user");
exit();
} else {
$tmLast = $currtime; // 更新最後活動時間
}
// 驗證資料庫帳密
include('class/dbclass.inc');
$q = new DB_Sql;
$q->connect($Host, $Database, $User, $Password);
$query = "SELECT idUser FROM User WHERE chrUserName='$user' AND chrPasswd='$password'";
$q->query($query);
if (!$q->num_rows()) {
$error = urlencode('密碼錯誤或無權限用戶!');
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);
$hasPrivilege = 0;
foreach ($pieces as $p) {
if (strtolower($user) == trim($p)) {
$hasPrivilege = 1;
break;
}
}
if (!$hasPrivilege) {
if ($fileName == '') $fileName = $PHP_SELF;
$error = urlencode('您無權查看此頁面!');
header("Location: login2.php?fileName=$fileName&error=$error&id=$id");
exit();
}
?>
PHPSESSID= 參數,解決禁用 Cookie 環境下的 Session 追蹤security2.php 以 $durtime 控制閒置逾時,預設 300 秒security1.php 維護超級用戶白名單,security2.php 驗證一般用戶資料庫帳密888 導向修改頁面$_SESSION 超全域陣列(PHP 4.1.0+)替代已棄用的 session_register()password_hash() / password_verify() 加密存儲