首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

利用 Session 實現 Web 頁面權限保護

     編輯:PHP 綜合知識

應用場景

典型的前台瀏覽與後台管理分離架構中,需要根據用戶角色(無權訪客、一般授權用戶、超級管理員)動態控制頁面存取權限。PHP 4 引入的 Session 機制為此提供了原生支援。

核心需求

  • 同一站點下,不同權限用戶看到不同頁面
  • 解決瀏覽器禁用 Cookie 導致 Session 失效問題
  • 防止權限被盜用(Session 存活期預設為瀏覽器關閉)

實現架構

採用「保護模板」機制:在需保護的頁面頂部引入對應等級的驗證文件:

  • 一般頁面:include('security2.php');
  • 特權頁面:include('security1.php'); include('security2.php');

核心代碼解析

1. 登入頁面 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>

2. 一般用戶驗證 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
}
?>

3. 特殊用戶驗證 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();
}
?>

關鍵技術點總結

  1. URL 傳遞 Session ID:所有跳轉均附加 PHPSESSID= 參數,解決禁用 Cookie 環境下的 Session 追蹤
  2. 逾時自動登出:security2.php 以 $durtime 控制閒置逾時,預設 300 秒
  3. 分層權限控制:security1.php 維護超級用戶白名單,security2.php 驗證一般用戶資料庫帳密
  4. 預設密碼強制變更:登入時檢測密碼為 888 導向修改頁面

安全性建議

  • 生產環境應改用 $_SESSION 超全域陣列(PHP 4.1.0+)替代已棄用的 session_register()
  • 密碼務必採用 password_hash() / password_verify() 加密存儲
  • 所有 SQL 查詢需使用預處理語句防止注入
  • 敏感操作頁面建議加入 CSRF Token 驗證
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved