ThinkPHP 6.0企业级RBAC权限管理系统开发实战教程

2025-11-07 0 217

项目背景与需求分析

在现代企业应用开发中,权限管理是系统安全的核心组成部分。RBAC(Role-Based Access Control)基于角色的访问控制模型,通过角色这一中间层将用户和权限解耦,大大简化了权限管理。本教程将基于ThinkPHP 6.0框架,从零开始构建一个完整的企业级RBAC权限管理系统

系统核心功能需求

  • 多层级角色管理,支持角色继承
  • 细粒度权限控制,支持按钮级权限
  • 部门数据权限隔离
  • 操作日志审计追踪
  • 菜单动态生成

技术架构设计

数据库设计

-- 用户表
CREATE TABLE `admin_user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(50) NOT NULL COMMENT '用户名',
    `password` varchar(255) NOT NULL COMMENT '密码',
    `realname` varchar(50) DEFAULT NULL COMMENT '真实姓名',
    `department_id` int(11) DEFAULT NULL COMMENT '部门ID',
    `status` tinyint(1) DEFAULT '1' COMMENT '状态:1正常 0禁用',
    `create_time` datetime DEFAULT NULL,
    `update_time` datetime DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 角色表
CREATE TABLE `admin_role` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(50) NOT NULL COMMENT '角色名称',
    `description` varchar(255) DEFAULT NULL COMMENT '角色描述',
    `parent_id` int(11) DEFAULT '0' COMMENT '父角色ID',
    `data_scope` tinyint(1) DEFAULT '1' COMMENT '数据权限范围',
    `status` tinyint(1) DEFAULT '1',
    `create_time` datetime DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 权限节点表
CREATE TABLE `admin_permission` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(50) NOT NULL COMMENT '权限名称',
    `path` varchar(255) NOT NULL COMMENT '权限路径',
    `type` tinyint(1) DEFAULT '1' COMMENT '类型:1菜单 2按钮',
    `icon` varchar(50) DEFAULT NULL COMMENT '图标',
    `sort` int(11) DEFAULT '0' COMMENT '排序',
    `parent_id` int(11) DEFAULT '0' COMMENT '父节点ID',
    `status` tinyint(1) DEFAULT '1',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

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

-- 角色权限关联表
CREATE TABLE `admin_role_permission` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `role_id` int(11) NOT NULL,
    `permission_id` int(11) NOT NULL,
    PRIMARY KEY (`id`),
    KEY `role_id` (`role_id`),
    KEY `permission_id` (`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

核心功能实现

1. 基础模型构建

用户模型 (app/model/AdminUser.php)

<?php
namespace appmodel;

use thinkModel;
use thinkmodelconcernSoftDelete;

class AdminUser extends Model
{
    use SoftDelete;
    
    protected $name = 'admin_user';
    protected $autoWriteTimestamp = true;
    protected $deleteTime = 'delete_time';
    
    // 密码自动加密
    public function setPasswordAttr($value)
    {
        return password_hash($value, PASSWORD_DEFAULT);
    }
    
    // 用户角色关联
    public function roles()
    {
        return $this->belongsToMany('AdminRole', 'admin_user_role', 'role_id', 'user_id');
    }
    
    // 获取用户所有权限
    public function getPermissions()
    {
        $permissions = [];
        $roles = $this->roles()->with('permissions')->select();
        
        foreach ($roles as $role) {
            foreach ($role->permissions as $permission) {
                $permissions[$permission->id] = $permission->toArray();
            }
        }
        
        return array_values($permissions);
    }
    
    // 验证用户权限
    public function hasPermission($path)
    {
        $permissions = $this->getPermissions();
        foreach ($permissions as $permission) {
            if ($permission['path'] === $path) {
                return true;
            }
        }
        return false;
    }
}

2. 权限验证中间件

<?php
namespace appmiddleware;

use thinkfacadeSession;

class AuthPermission
{
    public function handle($request, Closure $next)
    {
        // 排除登录页面
        if ($request->controller() === 'Login') {
            return $next($request);
        }
        
        // 检查用户登录状态
        $user = Session::get('admin_user');
        if (!$user) {
            return redirect('/admin/login');
        }
        
        // 权限验证
        $currentPath = $request->controller() . '/' . $request->action();
        if (!$user->hasPermission($currentPath)) {
            if ($request->isAjax()) {
                return json(['code' => 403, 'msg' => '权限不足']);
            } else {
                return view('common/error', ['msg' => '您没有访问该页面的权限']);
            }
        }
        
        return $next($request);
    }
}

3. 角色管理服务

<?php
namespace appservice;

use appmodelAdminRole;
use thinkException;

class RoleService
{
    /**
     * 创建角色
     */
    public function createRole($data)
    {
        try {
            $role = new AdminRole();
            $role->save($data);
            
            // 处理权限关联
            if (!empty($data['permission_ids'])) {
                $role->permissions()->saveAll($data['permission_ids']);
            }
            
            return $role->id;
        } catch (Exception $e) {
            throw new Exception('角色创建失败:' . $e->getMessage());
        }
    }
    
    /**
     * 获取角色树形结构
     */
    public function getRoleTree($parentId = 0)
    {
        $roles = AdminRole::where('parent_id', $parentId)
            ->where('status', 1)
            ->order('id', 'asc')
            ->select();
        
        $tree = [];
        foreach ($roles as $role) {
            $node = $role->toArray();
            $node['children'] = $this->getRoleTree($role->id);
            $tree[] = $node;
        }
        
        return $tree;
    }
    
    /**
     * 获取角色所有子角色ID
     */
    public function getRoleChildrenIds($roleId)
    {
        $childrenIds = [$roleId];
        $children = AdminRole::where('parent_id', $roleId)->column('id');
        
        foreach ($children as $childId) {
            $childrenIds = array_merge($childrenIds, $this->getRoleChildrenIds($childId));
        }
        
        return $childrenIds;
    }
}

高级特性实现

1. 数据权限控制

<?php
namespace appservice;

class DataPermissionService
{
    const SCOPE_ALL = 1;      // 全部数据
    const SCOPE_DEPT = 2;     // 本部门数据
    const SCOPE_SELF = 3;     // 本人数据
    const SCOPE_CUSTOM = 4;   // 自定义部门
    
    /**
     * 应用数据权限
     */
    public function applyDataScope($query, $user, $tableAlias = '')
    {
        $prefix = $tableAlias ? $tableAlias . '.' : '';
        
        // 超级管理员拥有所有数据权限
        if ($user->is_super_admin) {
            return $query;
        }
        
        $maxDataScope = $this->getUserMaxDataScope($user);
        
        switch ($maxDataScope) {
            case self::SCOPE_SELF:
                $query->where($prefix . 'create_user_id', $user->id);
                break;
            case self::SCOPE_DEPT:
                $query->where($prefix . 'department_id', $user->department_id);
                break;
            case self::SCOPE_CUSTOM:
                $deptIds = $this->getUserCustomDeptIds($user);
                $query->whereIn($prefix . 'department_id', $deptIds);
                break;
        }
        
        return $query;
    }
    
    /**
     * 获取用户最大数据权限范围
     */
    private function getUserMaxDataScope($user)
    {
        $minScope = self::SCOPE_ALL;
        $roles = $user->roles;
        
        foreach ($roles as $role) {
            if ($role->data_scope data_scope;
            }
        }
        
        return $minScope;
    }
}

2. 动态菜单生成

<?php
namespace appservice;

class MenuService
{
    /**
     * 生成用户菜单树
     */
    public function generateUserMenu($user)
    {
        $permissions = $user->getPermissions();
        $menuPermissions = array_filter($permissions, function($item) {
            return $item['type'] == 1; // 菜单类型
        });
        
        return $this->buildMenuTree($menuPermissions);
    }
    
    /**
     * 构建菜单树
     */
    private function buildMenuTree($permissions, $parentId = 0)
    {
        $tree = [];
        
        foreach ($permissions as $permission) {
            if ($permission['parent_id'] == $parentId) {
                $node = [
                    'id' => $permission['id'],
                    'name' => $permission['name'],
                    'path' => $permission['path'],
                    'icon' => $permission['icon'],
                    'sort' => $permission['sort']
                ];
                
                $children = $this->buildMenuTree($permissions, $permission['id']);
                if ($children) {
                    $node['children'] = $children;
                }
                
                $tree[] = $node;
            }
        }
        
        // 按排序字段排序
        usort($tree, function($a, $b) {
            return $a['sort']  $b['sort'];
        });
        
        return $tree;
    }
}

控制器实现示例

用户管理控制器

<?php
namespace appcontrolleradmin;

use appBaseController;
use appmodelAdminUser;
use appserviceDataPermissionService;
use thinkfacadeRequest;

class User extends BaseController
{
    protected $middleware = ['appmiddlewareAuthPermission'];
    
    /**
     * 用户列表
     */
    public function index()
    {
        $page = Request::param('page', 1);
        $limit = Request::param('limit', 20);
        $search = Request::param('search', '');
        
        $query = AdminUser::with(['roles', 'department']);
        
        // 应用数据权限
        $user = session('admin_user');
        $dataService = new DataPermissionService();
        $query = $dataService->applyDataScope($query, $user);
        
        // 搜索条件
        if ($search) {
            $query->whereLike('username|realname', "%{$search}%");
        }
        
        $list = $query->paginate([
            'list_rows' => $limit,
            'page' => $page
        ]);
        
        return json([
            'code' => 0,
            'data' => $list->items(),
            'count' => $list->total(),
            'msg' => 'success'
        ]);
    }
    
    /**
     * 创建用户
     */
    public function create()
    {
        $data = Request::post();
        
        try {
            $user = new AdminUser();
            $user->save($data);
            
            // 分配角色
            if (!empty($data['role_ids'])) {
                $user->roles()->saveAll($data['role_ids']);
            }
            
            return json(['code' => 0, 'msg' => '创建成功']);
        } catch (Exception $e) {
            return json(['code' => 1, 'msg' => '创建失败:' . $e->getMessage()]);
        }
    }
}

前端权限控制实现

Vue.js权限指令

// 权限指令
Vue.directive('permission', {
    inserted: function (el, binding) {
        const permissions = Vue.prototype.$permissions || [];
        const value = binding.value;
        
        if (!permissions.includes(value)) {
            el.parentNode && el.parentNode.removeChild(el);
        }
    }
});

// 使用示例
<button v-permission="'user/create'">创建用户</button>
<button v-permission="'user/delete'">删除用户</button>

系统部署与优化

性能优化建议

  • 使用Redis缓存权限数据,减少数据库查询
  • 实现权限变更时的缓存更新机制
  • 对频繁查询的用户角色关系进行预加载
  • 使用数据库索引优化关联查询性能

安全加固措施

  • 实现密码强度策略和定期更换机制
  • 添加登录失败次数限制和IP封禁
  • 记录详细的操作日志用于安全审计
  • 定期进行权限复核和清理

总结

通过本教程,我们完整实现了一个基于ThinkPHP 6.0的企业级RBAC权限管理系统。系统具备以下特点:

  • 灵活的角色权限分配机制
  • 多层次的数据权限控制
  • 动态菜单生成和前端权限控制
  • 完整的操作日志和审计功能
  • 良好的扩展性和维护性

该系统可以作为企业级应用的基础权限框架,根据具体业务需求进行扩展和定制。ThinkPHP 6.0的现代特性如中间件、服务层等让代码结构更加清晰,维护更加方便。

在实际项目开发中,建议根据具体业务场景调整权限模型,并持续优化系统性能和安全性。希望本教程能为您的ThinkPHP项目开发提供有价值的参考。

ThinkPHP 6.0企业级RBAC权限管理系统开发实战教程
收藏 (0) 打赏

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

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

淘吗网 thinkphp ThinkPHP 6.0企业级RBAC权限管理系统开发实战教程 https://www.taomawang.com/server/thinkphp/1394.html

常见问题

相关文章

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

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