一般web系統操作人員多時都會需求權限管理,一來限制操作範圍,二來限制數據公開度。
現在最流行的一個模式爲 RBAC (Role-Based Access Control) 基於角色的訪問控制。設定權限範圍定義到角色中,然後再分配到每個用戶。
這裏僅以一般後臺管理系統爲例,敘說數據結構:
需求:
菜單需要針對不同部門使用不同的菜單結構。
權限項能精確到頁面中某個內容或局部功能。
基本要求:沒有權限的菜單,頁面中內容或鏈接禁止顯示。
表結構
CREATE TABLE `power_item` ( `power_item_id` int UNSIGNED primary key auto_increment, `name` varchar(35) not null comment '權限項名稱', `code` varchar(80) unique not null comment '權限項代碼', `power_item_group_id` int unsigned not null comment '權限項組ID', `status` enum('disable','enable') NOT NULL DEFAULT 'enable' COMMENT '啓用或禁用,enable爲啓用', `comment` varchar(1000) not null default '' comment '備註說明', `created_at` int unsigned not null comment '創建時間', `updated_at` int unsigned not null comment '修改時間' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='權限項表'; CREATE TABLE `power_item_group` ( `power_item_group_id` int UNSIGNED primary key auto_increment, `name` varchar(35) not null comment '權限項組名稱', `comment` varchar(1000) not null default '' comment '備註說明', `created_at` int unsigned not null comment '創建時間', `updated_at` int unsigned not null comment '修改時間' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='權限項組表'; CREATE TABLE `power_role` ( `power_role_id` int UNSIGNED primary key auto_increment, `name` varchar(35) not null comment '角色名', `status` enum('enable','disable') not null default 'enable' comment '啓用或禁用,enable爲啓用', `comment` varchar(1000) not null default '' comment '備註說明', `created_at` int unsigned not null comment '創建時間', `updated_at` int unsigned not null comment '修改時間' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='角色表'; CREATE TABLE `power_role_item` ( `id` int UNSIGNED primary key auto_increment, `power_role_id` int unsigned not null comment '角色ID', `power_item_id` int unsigned not null comment '權限項ID', unique key role_item(power_role_id,power_item_id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='角色與權限項關聯表'; CREATE TABLE `power_role_admin` ( `id` int UNSIGNED primary key auto_increment, `power_role_id` int unsigned not null comment '角色ID', `admin_id` int unsigned not null comment '管理員ID', unique key role_admin(power_role_id,admin_id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='角色與管理員關聯表'; CREATE TABLE `power_menu_group` ( `power_menu_group_id` int UNSIGNED primary key auto_increment, `name` varchar(35) not null comment '菜單組名', `comment` varchar(1000) not null default '' comment '備註說明', `created_at` int unsigned not null comment '創建時間', `updated_at` int unsigned not null comment '修改時間' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='菜單組表'; CREATE TABLE `power_menu` ( `power_menu_id` int UNSIGNED primary key auto_increment, `name` varchar(35) not null comment '菜單名', `url` varchar(60) not null comment '鏈接地址', `power_item_id` int unsigned not null default 0 comment '關聯權限項ID', `comment` varchar(1000) not null default '' comment '備註說明', `created_at` int unsigned not null comment '創建時間', `updated_at` int unsigned not null comment '修改時間' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='菜單表'; CREATE TABLE `power_menu_level` ( `id` int UNSIGNED primary key auto_increment, `power_menu_id` int unsigned not null default 0 comment '菜單ID', `power_menu_group_id` int unsigned not null default 0 comment '所屬菜單組ID', `parent_id` int unsigned not null default 0 comment '上級層級ID', `sort` smallint unsigned not null default 0 comment '排序值,大到小', unique key menu_level(power_menu_id,power_menu_group_id,parent_id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='菜單層級關聯表';
關聯關係圖
對應關係
角色與權限項通過 power_role_item 表隨意組合
角色與管理員通過 power_role_admin 表隨意組合
菜單與菜單組通過 power_menu_level 表隨意組合(包含菜單層級關係)
設計思想
角色只是劃分範圍或添加維度方便理解,實際使用中很多管理員扮演了多種角色,所以一個管理員允許同時擁有N個角色。
權限項相當於一把鎖,程序在關鍵地方安裝對應的鎖,然後把這些鎖的鑰匙分配給不同的角色,所以權限項與角色之間是多對多關係,即一個權限項可以關聯多個角色,而一個角色也可以關聯多個權限項。
權限項組只是爲了把衆多的權限項進行簡單的分組,以便角色在勾選權限項時能把權限項分組展示,比如,權限管理相關,會員管理相關,訂單管理相關等,這樣在勾選時會更容易操作。
菜單可以關聯到對應的權限項,這樣可以過濾掉沒有權限的菜單顯示,爲了方便不同部門菜單結構不同的目的,額外添加了菜單層級與菜單組,這樣一來,每個管理員只顯示自己所在的菜單組的菜單結構,中間相對複雜點的就是菜單結構組合處理,power_menu_level 表中需要保存當前菜單,上級菜單,及菜單組,和排序。
備註說明
角色設計中棄用所謂的上級角色關係(即角色繼承)感覺很高尚的設計,實際容易造成誤解,誤操作,程序複雜化等問題,比如繼承會擁有上級權限那麼對實際分配人員對角色的理解就不僅限於當前角色還得考慮上級角色否則容易造成權限分配過度,再者繼承的權限在權限查詢中存在着遞歸結構,複雜化判斷程序,如果不繼承權限那這個功能形同虛設,當然如果只是爲了給角色分類,完全可以增加一個角色組表,進行區分。
菜單棄用了單一預定義好的結構,使用了可自定義的菜單結構,也只是爲了滿足不同部門菜單結構的需求,當前這塊功能並非必需的,在實際應用中是可選的。
以上內容爲個人觀點或想法,如有不妥還請糾正。
歡迎安裝
composer require xihuan/laravel-crbac