当前位置:首页 > 问答 > 正文

用户认证|权限管理 php 源代码登录权限设计与实现方案

PHP登录权限设计与实现方案

场景引入
想象一下,你刚开发了一个企业后台管理系统,结果实习生误删了生产数据库,或者市场部的同事看到了财务部的敏感数据……这种混乱的场面,往往源于权限管理的缺失,我们就用PHP手把手实现一套既安全又灵活的登录认证与权限控制系统。

用户认证|权限管理 php 源代码登录权限设计与实现方案


基础架构设计

数据库表结构(MySQL示例)

-- 用户表
CREATE TABLE `users` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `username` VARCHAR(50) UNIQUE NOT NULL,
  `password` VARCHAR(255) NOT NULL,  -- 存储bcrypt哈希值
  `email` VARCHAR(100) UNIQUE NOT NULL,
  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 角色表
CREATE TABLE `roles` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(30) UNIQUE NOT NULL  -- 如:admin, editor, viewer
);
-- 用户-角色关联表
CREATE TABLE `user_roles` (
  `user_id` INT NOT NULL,
  `role_id` INT NOT NULL,
  PRIMARY KEY (`user_id`, `role_id`),
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`),
  FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`)
);
-- 权限表(RBAC模型)
CREATE TABLE `permissions` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `code` VARCHAR(50) UNIQUE NOT NULL,  -- 如:create_post
  `description` VARCHAR(200) NOT NULL
);
-- 角色-权限关联表
CREATE TABLE `role_permissions` (
  `role_id` INT NOT NULL,
  `permission_id` INT NOT NULL,
  PRIMARY KEY (`role_id`, `permission_id`)
);

核心代码实现

密码安全处理

// 注册时密码加密
function hashPassword($plainPassword) {
    return password_hash($plainPassword, PASSWORD_BCRYPT, ['cost' => 12]);
}
// 登录验证
function verifyPassword($inputPassword, $hashedPassword) {
    return password_verify($inputPassword, $hashedPassword);
}

会话管理类

class Auth {
    private $db;
    public function __construct($dbConnection) {
        $this->db = $dbConnection;
        session_start();
    }
    // 用户登录
    public function login($username, $password) {
        $stmt = $this->db->prepare("SELECT id, password FROM users WHERE username = ?");
        $stmt->execute([$username]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($user && verifyPassword($password, $user['password'])) {
            $_SESSION['user_id'] = $user['id'];
            return true;
        }
        return false;
    }
    // 检查是否登录
    public function isLoggedIn() {
        return isset($_SESSION['user_id']);
    }
    // 获取当前用户角色
    public function getUserRoles() {
        if (!$this->isLoggedIn()) return [];
        $stmt = $this->db->prepare("
            SELECT r.name FROM roles r
            JOIN user_roles ur ON r.id = ur.role_id
            WHERE ur.user_id = ?
        ");
        $stmt->execute([$_SESSION['user_id']]);
        return $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
    }
}

权限控制实现

中间件式权限检查

// 权限检查中间件
function hasPermission($requiredPermission) {
    $auth = new Auth($db);
    if (!$auth->isLoggedIn()) return false;
    $stmt = $db->prepare("
        SELECT COUNT(*) FROM role_permissions rp
        JOIN permissions p ON rp.permission_id = p.id
        JOIN user_roles ur ON rp.role_id = ur.role_id
        WHERE ur.user_id = ? AND p.code = ?
    ");
    $stmt->execute([$_SESSION['user_id'], $requiredPermission]);
    return $stmt->fetchColumn() > 0;
}
// 使用示例:删除文章前检查权限
if (!hasPermission('delete_post')) {
    die('抱歉,您没有删除权限');
}

动态菜单渲染

// 根据权限生成导航菜单
function generateMenu() {
    $menuItems = [
        ['label' => '仪表盘', 'permission' => 'view_dashboard'],
        ['label' => '内容管理', 'permission' => 'manage_content'],
        ['label' => '用户管理', 'permission' => 'manage_users']
    ];
    $output = '<ul>';
    foreach ($menuItems as $item) {
        if (hasPermission($item['permission'])) {
            $output .= "<li>{$item['label']}</li>";
        }
    }
    $output .= '</ul>';
    return $output;
}

安全增强措施

  1. CSRF防护
    // 生成CSRF令牌
    function generateCsrfToken() {
     if (empty($_SESSION['csrf_token'])) {
         $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
     }
     return $_SESSION['csrf_token'];
    }

// 验证表单提交 if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) { die('非法请求'); }


2. **登录失败限制**  
```php
// 记录失败尝试
if ($loginFailed) {
    $cacheKey = "login_attempts_{$_SERVER['REMOTE_ADDR']}";
    $attempts = $cache->get($cacheKey) ?: 0;
    $cache->set($cacheKey, ++$attempts, 3600); // 1小时限制
    if ($attempts > 5) {
        die('尝试次数过多,请稍后再试');
    }
}

实际应用建议

  1. 权限粒度控制
  • 功能级权限(如:发布文章)
  • 数据级权限(如:只能编辑自己部门的文档)
  1. 定期审计
    -- 记录关键操作
    CREATE TABLE `audit_logs` (
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `user_id` INT NOT NULL,
    `action` VARCHAR(100) NOT NULL,  -- 如:delete_user
    `ip_address` VARCHAR(45) NOT NULL,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );

:这套方案实现了:

用户认证|权限管理 php 源代码登录权限设计与实现方案

  • 基于角色的访问控制(RBAC)
  • 密码安全存储(bcrypt哈希)
  • 细粒度的权限检查
  • 可扩展的审计日志

根据2025年的安全实践建议,建议每季度进行一次权限复核,并始终使用预处理语句防止SQL注入。

发表评论