基于权限等级的PHP页面访问控制实现技术问询
没问题,我来一步步帮你把这套基于权限等级的PHP页面访问控制给完善好,从登录逻辑到权限校验全流程捋清楚,保证安全又好用:
一、完善登录页的核心逻辑
首先要注意:绝对不能明文存储密码,所以数据库里的password字段应该存哈希值(比如用PHP的password_hash()生成)。登录时用password_verify()验证,而不是直接对比字符串。另外必须用预处理语句防止SQL注入。
补全后的登录页代码示例:
<?php session_start(); // 防止已登录用户重复进入登录页 if (isset($_SESSION["username"])) { header("Location: dashboard.php"); // 跳转到默认首页 exit(); } $error = ""; if (isset($_POST['username']) && isset($_POST['password'])) { // 连接数据库(请替换成你的数据库信息) $conn = mysqli_connect("localhost", "db_user", "db_password", "db_name"); if (!$conn) { die("数据库连接失败: " . mysqli_connect_error()); } // 获取并过滤表单输入 $username = stripslashes(trim($_REQUEST['username'])); $password = trim($_REQUEST['password']); // 用预处理语句查询用户,彻底防止SQL注入 $stmt = mysqli_prepare($conn, "SELECT id, username, password, level FROM users WHERE username = ?"); mysqli_stmt_bind_param($stmt, "s", $username); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $user = mysqli_fetch_assoc($result); if ($user && password_verify($password, $user['password'])) { // 登录成功,将必要信息存入session $_SESSION["username"] = $user['username']; $_SESSION["level"] = $user['level']; // 关键:把权限等级存到session里 $_SESSION["user_id"] = $user['id']; // 根据权限跳转到对应页面 if ($user['level'] === 'admin') { header("Location: admin_panel.php"); } else { header("Location: user_dashboard.php"); } exit(); } else { $error = "用户名或密码错误"; } mysqli_stmt_close($stmt); mysqli_close($conn); } ?> <!-- HTML登录表单部分 --> <!DOCTYPE html> <html> <head> <title>登录</title> </head> <body> <?php if ($error): ?> <p style="color: red;"><?php echo $error; ?></p> <?php endif; ?> <form method="post" action=""> <label>用户名:</label> <input type="text" name="username" required><br> <label>密码:</label> <input type="password" name="password" required><br> <button type="submit">登录</button> </form> </body> </html>
二、升级
auth.php:加入权限校验逻辑 原来的auth.php只做了登录状态检查,现在要扩展成权限校验。我们让每个页面自己定义允许访问的权限等级,然后auth.php读取这个规则并校验,灵活性更高。
升级后的auth.php代码:
<?php session_start(); // 1. 首先检查是否登录(含权限信息) if (!isset($_SESSION["username"]) || !isset($_SESSION["level"])) { header("Location: login.php"); exit(); } // 2. 获取当前页面的允许权限规则 // 注意:每个受保护页面必须在引入auth.php前定义$allowed_levels变量 if (!isset($allowed_levels)) { // 默认规则:如果页面没定义权限,仅允许admin访问(可根据需求调整) $allowed_levels = ['admin']; } // 3. 权限校验逻辑 $user_level = $_SESSION["level"]; // admin拥有最高权限,直接放行 if ($user_level === 'admin') { return; } // 普通user检查是否在允许的权限列表里 if (!in_array($user_level, $allowed_levels)) { // 权限不足,跳转到无权限提示页或首页 header("Location: access_denied.php"); exit(); } ?>
三、给每个页面配置权限规则
在每个需要受保护的页面开头,先定义允许的权限等级,再引入auth.php。示例:
1. 普通用户专属页面(比如user_dashboard.php)
<?php // 允许user和admin访问 $allowed_levels = ['user', 'admin']; require_once 'auth.php'; ?> <!-- 页面内容 --> <h1>用户仪表盘</h1> <p>欢迎普通用户访问</p>
2. 管理员专属页面(比如admin_panel.php)
<?php // 仅允许admin访问 $allowed_levels = ['admin']; require_once 'auth.php'; ?> <!-- 页面内容 --> <h1>管理员控制面板</h1> <p>仅管理员可见的敏感操作内容</p>
3. 全登录用户可访问页面(比如首页index.php)
<?php // 所有登录用户(user和admin)都能访问 $allowed_levels = ['user', 'admin']; require_once 'auth.php'; ?> <!-- 页面内容 --> <h1>网站首页</h1> <p>所有登录用户均可浏览</p>
四、关键安全提醒
- 密码哈希:新用户注册时,必须用
password_hash($user_password, PASSWORD_DEFAULT)生成哈希值再存入数据库,永远不要明文存储密码 - SQL注入防护:全程使用预处理语句,绝对不要直接把用户输入拼接到SQL语句中
- 会话安全:可以在
session_start()前添加以下配置提升会话安全性:ini_set('session.cookie_secure', 1); // 仅HTTPS下传输session cookie ini_set('session.cookie_httponly', 1); // 禁止JS读取session cookie,防止XSS劫持 ini_set('session.use_strict_mode', 1); // 防止会话固定攻击 - 权限校验全覆盖:每个受保护页面必须引入
auth.php,不要跳过任何页面的校验 - 敏感信息不存session:session里只存username、level、user_id这类必要信息,绝对不要存密码等敏感内容
内容的提问来源于stack exchange,提问作者Ovakos
相关产品推荐
相关产品推荐

