ThinkPHP8企业级RBAC权限系统开发全攻略 | 后台权限管理实战

2025-08-08 0 662

从零构建高性能后台权限管理系统的完整方案

一、RBAC权限模型核心设计

基于角色的访问控制(RBAC)是现代后台系统的标配功能,我们采用五表结构设计:

1. 数据库表结构

# 用户表
CREATE TABLE `admin_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用户名',
  `password` varchar(255) NOT NULL COMMENT '密码',
  `status` tinyint(1) DEFAULT '1' COMMENT '状态',
  `create_time` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

# 角色表
CREATE TABLE `admin_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL COMMENT '角色名称',
  `description` varchar(255) DEFAULT NULL COMMENT '描述',
  `status` tinyint(1) DEFAULT '1' COMMENT '状态'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

# 用户角色关联表
CREATE TABLE `admin_user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

# 权限节点表
CREATE TABLE `admin_node` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL COMMENT '节点名称',
  `route` varchar(128) NOT NULL COMMENT '路由规则',
  `type` tinyint(1) DEFAULT '1' COMMENT '类型 1:菜单 2:操作',
  `pid` int(11) DEFAULT '0' COMMENT '父级ID',
  `sort` int(11) DEFAULT '0' COMMENT '排序'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

# 角色权限关联表
CREATE TABLE `admin_role_node` (
  `role_id` int(11) NOT NULL,
  `node_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

二、核心功能实现

1. 权限验证中间件

<?php
namespace appadminmiddleware;

use thinkfacadeSession;

class AuthCheck
{
    public function handle($request, Closure $next)
    {
        // 排除登录页
        if (!preg_match('/login/', $request->pathinfo())) {
            // 验证登录状态
            if (!Session::has('admin_user')) {
                return redirect('/admin/login');
            }
            
            // 超级管理员跳过验证
            if (Session::get('admin_user.id') != 1) {
                $this->checkAuth($request);
            }
        }
        
        return $next($request);
    }
    
    protected function checkAuth($request)
    {
        $route = strtolower($request->controller().'/'.$request->action());
        $allowNodes = Session::get('admin_user.nodes') ?: [];
        
        if (!in_array($route, $allowNodes)) {
            if ($request->isAjax()) {
                return json(['code'=>403, 'msg'=>'无权限访问']);
            } else {
                abort(403, '无权限访问');
            }
        }
    }
}

2. 权限树形结构生成

<?php
namespace appadminservice;

class NodeService
{
    public static function getTree($nodes)
    {
        $tree = [];
        foreach ($nodes as $node) {
            if ($node['pid'] == 0) {
                $tree[$node['id']] = $node;
            } else {
                $tree[$node['pid']]['children'][] = $node;
            }
        }
        return array_values($tree);
    }
    
    public static function getFlattenNodes($nodes)
    {
        $result = [];
        foreach ($nodes as $node) {
            $result[] = strtolower($node['route']);
            if (!empty($node['children'])) {
                $result = array_merge($result, self::getFlattenNodes($node['children']));
            }
        }
        return $result;
    }
}

三、后台功能实现

1. 用户登录与权限初始化

<?php
namespace appadmincontroller;

use thinkfacadeSession;
use appadminserviceNodeService;

class Login
{
    public function doLogin()
    {
        $username = input('post.username');
        $password = input('post.password');
        
        $user = AdminUser::where('username', $username)
            ->find();
            
        if (!$user || !password_verify($password, $user['password'])) {
            return json(['code'=>400, 'msg'=>'账号或密码错误']);
        }
        
        // 获取用户权限节点
        $nodes = $this->getUserNodes($user['id']);
        
        Session::set('admin_user', [
            'id' => $user['id'],
            'username' => $user['username'],
            'nodes' => NodeService::getFlattenNodes($nodes)
        ]);
        
        return json(['code'=>200, 'msg'=>'登录成功']);
    }
    
    protected function getUserNodes($userId)
    {
        $query = AdminNode::alias('n')
            ->join('admin_role_node rn', 'n.id = rn.node_id')
            ->join('admin_user_role ur', 'rn.role_id = ur.role_id')
            ->where('ur.user_id', $userId)
            ->where('n.status', 1)
            ->order('n.sort', 'desc')
            ->select();
            
        return NodeService::getTree($query->toArray());
    }
}

2. 动态菜单生成

<?php
namespace appadmincontroller;

class Index
{
    public function menu()
    {
        $menu = Session::get('admin_user.menu_tree') ?: [];
        return json([
            'code' => 200,
            'data' => $menu
        ]);
    }
}

// 前端Vue组件示例
<template>
  <el-menu router :default-active="$route.path">
    <template v-for="item in menuData">
      <el-submenu v-if="item.children" :index="item.route">
        <template #title>
          <i :class="item.icon"></i>
          <span>{{ item.name }}</span>
        </template>
        <el-menu-item 
          v-for="child in item.children" 
          :key="child.route" 
          :index="child.route"
        >
          {{ child.name }}
        </el-menu-item>
      </el-submenu>
      <el-menu-item v-else :index="item.route">
        <i :class="item.icon"></i>
        <span>{{ item.name }}</span>
      </el-menu-item>
    </template>
  </el-menu>
</template>

四、高级功能扩展

1. 数据权限控制

<?php
namespace appadminservice;

class DataScopeService
{
    public static function applyScope($query, $user)
    {
        // 获取用户数据权限范围
        $scope = self::getUserDataScope($user['id']);
        
        switch ($scope['type']) {
            case 1: // 全部数据
                break;
            case 2: // 自定义部门
                $query->whereIn('dept_id', $scope['dept_ids']);
                break;
            case 3: // 本部门
                $query->where('dept_id', $user['dept_id']);
                break;
            case 4: // 本人
                $query->where('user_id', $user['id']);
                break;
        }
        
        return $query;
    }
}

2. 操作日志记录

<?php
namespace appadminmiddleware;

class OperationLog
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        
        if ($request->isPost() || $request->isPut() || $request->isDelete()) {
            AdminLog::create([
                'user_id' => Session::get('admin_user.id'),
                'ip' => $request->ip(),
                'method' => $request->method(),
                'path' => $request->pathinfo(),
                'params' => json_encode($request->param(), JSON_UNESCAPED_UNICODE),
                'status' => $response->getCode(),
                'create_time' => time()
            ]);
        }
        
        return $response;
    }
}

五、性能优化方案

1. 权限缓存策略

<?php
namespace appadminservice;

use thinkfacadeCache;

class AuthCache
{
    const CACHE_PREFIX = 'admin_auth:';
    
    public static function getUserNodes($userId)
    {
        $cacheKey = self::CACHE_PREFIX . $userId;
        
        if (Cache::has($cacheKey)) {
            return Cache::get($cacheKey);
        }
        
        $nodes = self::fetchUserNodesFromDb($userId);
        Cache::set($cacheKey, $nodes, 3600);
        
        return $nodes;
    }
    
    public static function clearUserCache($userId)
    {
        Cache::delete(self::CACHE_PREFIX . $userId);
    }
}

2. 权限验证优化

<?php
namespace appadminservice;

class FastAuthCheck
{
    public static function check($route, $userId)
    {
        static $userNodes = [];
        
        if (!isset($userNodes[$userId])) {
            $userNodes[$userId] = AuthCache::getUserNodes($userId);
        }
        
        return in_array($route, $userNodes[$userId]);
    }
}

项目部署建议

  • 使用Redis存储会话和权限缓存
  • 定期归档操作日志表
  • 关键操作增加二次验证
  • 实现权限变更实时通知机制

©2023 ThinkPHP实战开发社区 | 原创内容转载请注明出处

ThinkPHP8企业级RBAC权限系统开发全攻略 | 后台权限管理实战
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 thinkphp ThinkPHP8企业级RBAC权限系统开发全攻略 | 后台权限管理实战 https://www.taomawang.com/server/thinkphp/774.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务