项目背景与需求分析
在现代企业应用开发中,权限管理是系统安全的核心组成部分。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项目开发提供有价值的参考。

