一、RBAC 模型简介
1.1 什么是 RBAC 模型
RBAC(Role-Based Access Control)即基于角色的访问控制,它是一种通过对角色的权限分配来实现对用户访问权限管理的方法。在一个系统中,不同的用户可能具有不同的角色,比如管理员、普通用户等,每个角色被赋予特定的权限,用户通过拥有的角色来获得相应的权限。
1.2 RBAC 模型的基本组成
- 用户(User):系统的使用者,例如在一个电商系统中,买家和卖家都是用户。
- 角色(Role):具有一定权限的集合,比如在一个企业管理系统中,有经理、员工等角色。
- 权限(Permission):对系统资源的操作许可,比如在文件管理系统中,读取、写入、删除文件就是不同的权限。
二、ThinkPHP 中 RBAC 模型的落地
2.1 数据库设计
用户表(user)
// 假设使用 MySQL 数据库,以下是用户表结构示例 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(100) NOT NULL, `role_id` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;// 注释:这里的
role_id用于关联角色表,通过这个字段可以知道用户所属的角色。角色表(role)
CREATE TABLE `role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `role_name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;// 注释:存储角色的名称等信息。
权限表(permission)
CREATE TABLE `permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `permission_name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;// 注释:记录各种权限的名称。
角色 - 权限关系表(role_permission)
CREATE TABLE `role_permission` ( `role_id` int(11) NOT NULL, `permission_id` int(11) NOT NULL, PRIMARY KEY (`role_id`, `permission_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;// 注释:通过这个表来建立角色和权限之间的多对多关系。
2.2 模型创建
在 ThinkPHP 中创建相应的模型类。
User 模型
<?php namespace app\model; use think\Model; class User extends Model { protected $table = 'user'; // 关联角色模型 public function role() { return $this->belongsTo('Role'); } }// 注释:通过
role方法可以获取用户所属的角色信息。Role 模型
<?php namespace app\model; use think\Model; class Role extends Model { protected $table = 'role'; // 关联权限模型,多对多关系 public function permissions() { return $this->belongsToMany('Permission', 'role_permission', 'permission_id', 'role_id'); } }// 注释:通过
permissions方法可以获取角色所拥有的权限集合。Permission 模型
<?php namespace app\model; use think\Model; class Permission extends Model { protected $table = 'permission'; }
2.3 权限验证
在控制器中进行权限验证。
<?php
namespace app\controller;
use app\model\User;
use think\Controller;
class Index extends Controller
{
public function index()
{
// 获取当前登录用户
$user = User::find(1); // 这里假设用户 ID 为 1
if ($user) {
// 获取用户角色
$role = $user->role;
if ($role) {
// 获取角色权限
$permissions = $role->permissions;
// 假设这里有一个权限名称为 'view_index'
$hasPermission = false;
foreach ($permissions as $permission) {
if ($permission->permission_name === 'view_index') {
$hasPermission = true;
break;
}
}
if ($hasPermission) {
return '你有权限访问该页面';
} else {
return '你没有权限访问该页面';
}
}
}
return '用户未登录或不存在';
}
}
// 注释:这段代码首先获取当前登录用户,然后通过用户关联的角色获取角色的权限,最后判断用户是否有访问当前页面的权限。
三、RBAC 模型的扩展方案
3.1 基于部门的权限扩展
部门表(department)
CREATE TABLE `department` ( `id` int(11) NOT NULL AUTO_INCREMENT, `department_name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;// 注释:用于存储部门信息。
用户 - 部门关系表(user_department)
CREATE TABLE `user_department` ( `user_id` int(11) NOT NULL, `department_id` int(11) NOT NULL, PRIMARY KEY (`user_id`, `department_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;// 注释:建立用户和部门之间的多对多关系。
扩展权限验证逻辑 在原来的权限验证基础上,加入部门相关的权限判断。
<?php
namespace app\controller;
use app\model\User;
use think\Controller;
class Index extends Controller
{
public function index()
{
// 获取当前登录用户
$user = User::find(1); // 这里假设用户 ID 为 1
if ($user) {
// 获取用户角色
$role = $user->role;
if ($role) {
// 获取角色权限
$permissions = $role->permissions;
// 假设这里有一个权限名称为 'view_index'
$hasPermission = false;
foreach ($permissions as $permission) {
if ($permission->permission_name === 'view_index') {
$hasPermission = true;
break;
}
}
// 加入部门权限判断
$departments = $user->departments;
foreach ($departments as $department) {
// 假设部门也有相关权限存储在 department_permission 表中
$departmentPermissions = $department->permissions;
foreach ($departmentPermissions as $departmentPermission) {
if ($departmentPermission->permission_name === 'view_index') {
$hasPermission = true;
break 2;
}
}
}
if ($hasPermission) {
return '你有权限访问该页面';
} else {
return '你没有权限访问该页面';
}
}
}
return '用户未登录或不存在';
}
}
// 注释:这里在角色权限验证的基础上,又加入了部门权限的验证,如果用户所属部门有相应权限,也认为用户有权限访问。
3.2 动态权限分配
创建动态权限表(dynamic_permission)
CREATE TABLE `dynamic_permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `permission_name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;// 注释:用于存储动态分配给用户的权限。
实现动态权限分配逻辑 在用户登录或其他操作时,可以根据业务需求动态分配权限。
<?php
namespace app\controller;
use app\model\User;
use think\Controller;
class Index extends Controller
{
public function index()
{
// 获取当前登录用户
$user = User::find(1); // 这里假设用户 ID 为 1
if ($user) {
// 先检查角色和部门权限
$role = $user->role;
$departments = $user->departments;
$hasPermission = false;
if ($role) {
$permissions = $role->permissions;
foreach ($permissions as $permission) {
if ($permission->permission_name === 'view_index') {
$hasPermission = true;
break;
}
}
}
if (!$hasPermission && $departments) {
foreach ($departments as $department) {
$departmentPermissions = $department->permissions;
foreach ($departmentPermissions as $departmentPermission) {
if ($departmentPermission->permission_name === 'view_index') {
$hasPermission = true;
break 2;
}
}
}
}
// 再检查动态权限
$dynamicPermissions = $user->dynamicPermissions;
foreach ($dynamicPermissions as $dynamicPermission) {
if ($dynamicPermission->permission_name === 'view_index') {
$hasPermission = true;
break;
}
}
if ($hasPermission) {
return '你有权限访问该页面';
} else {
return '你没有权限访问该页面';
}
}
return '用户未登录或不存在';
}
}
// 注释:这段代码在原来的权限验证基础上,又加入了动态权限的验证,使得权限分配更加灵活。
四、应用场景
4.1 企业管理系统
在企业管理系统中,不同部门的员工可能具有不同的权限。例如,财务部门的员工可以查看和修改财务相关的报表,而销售部门的员工只能查看销售数据。通过 RBAC 模型,可以很方便地为不同部门的员工分配相应的角色和权限,同时可以根据部门的特点进行权限扩展。
4.2 电商系统
在电商系统中,买家和卖家具有不同的权限。买家可以浏览商品、下单购买等,而卖家可以管理店铺、发布商品等。通过 RBAC 模型,可以清晰地划分不同用户角色的权限,并且可以根据业务需求进行动态权限分配,比如对于一些特殊的促销活动,为特定的用户群体分配额外的权限。
五、技术优缺点
5.1 优点
- 管理方便:通过角色来管理权限,而不是直接对用户进行权限分配,大大减少了管理的复杂度。
- 灵活性高:可以很方便地进行权限扩展,如基于部门的权限扩展和动态权限分配。
- 安全性强:明确了不同用户的权限,减少了越权操作的可能性。
5.2 缺点
- 角色数量过多可能导致混乱:如果系统中角色数量过多,可能会导致权限分配不清晰,难以管理。
- 初期配置工作量较大:需要花费一定的时间来设计数据库结构和配置角色权限。
六、注意事项
6.1 角色和权限的合理划分
在设计角色和权限时,要充分考虑业务需求,确保角色和权限的划分合理,避免出现权限漏洞或过于复杂的情况。
6.2 数据一致性
在进行权限分配和修改时,要注意保持数据的一致性,特别是在多对多关系的表中,要确保数据的准确性。
6.3 系统性能
随着系统用户和权限数量的增加,权限验证的性能可能会受到影响。可以考虑使用缓存等技术来提高性能。
七、文章总结
本文介绍了 ThinkPHP 中权限控制的 RBAC 模型的落地与扩展方案。首先介绍了 RBAC 模型的基本概念,然后详细说明了在 ThinkPHP 中如何进行数据库设计、模型创建和权限验证。接着介绍了基于部门的权限扩展和动态权限分配的方案,并分析了其应用场景、技术优缺点和注意事项。通过合理使用 RBAC 模型及其扩展方案,可以有效地管理系统的权限,提高系统的安全性和灵活性。
评论
围绕“ThinkPHP权限控制的RBAC模型落地与扩展方案”参与讨论