本猿年初的時候接手了一套后臺系統(tǒng)抚垃,這套系統(tǒng)對于權(quán)限刷新了我的三觀(每個用戶對應(yīng)一個角色ROLEID趟大,用戶訪問的時候根據(jù)不同的ROLEID加載不同的模板文件铣焊,OK! A角色和B角色看到的頁面就不同了)
不提這梗了,本人解釋下自己對最基本的RBCA的理解曲伊,雖然簡單,但應(yīng)對大部分公司內(nèi)部系統(tǒng)已經(jīng)足夠了
一個URL通常代表著以下類型的資源:
- 一張網(wǎng)頁(Page):打開網(wǎng)頁可能伴隨著數(shù)據(jù)的查詢或修改,但這仍然是該類型資源的一部分
- 獲取數(shù)據(jù)(AjaxGet):只限于查詢岛蚤,不會對數(shù)據(jù)造成修改等影響
- 修改數(shù)據(jù)(AjaxUpdate):通常包括增加涤妒,刪除赚哗,修改
- 文件:這個暫時未考慮
RBCA模型中涉及以下幾個概念:
- 用戶(User) 即登錄的用戶本身,有一個用戶ID(定義uid)
- 角色(Role) 即這個用戶擁有幾個身份屿储,一個用戶可以有幾個角色,比如一家小公司的人事專員可能即使人事民褂,又是客服
- 權(quán)限(Access) access英語中的含義是訪問,引申為訪問的資源买羞,習慣上可以稱之為權(quán)限
下面舉例子:
小珍是XX公司的人事雹食,擁有人事專員和客服兩個角色
小李是XX公司的技術(shù),擁有技術(shù)專員的角色
人事專員可以查看A頁面吃挑,可以進行A頁面上的aa和ab操作
客服可以查看B頁面街立,可以進行B頁面上的ba和bb操作
技術(shù)專員可以查看C頁面,可以進行C頁面上的ca和cb操作
那么:
小珍可以打開A頁面和B頁面逛犹,可以進行aa,ab,ba,bb操作,但是想打開C頁面時會被提示沒有權(quán)限
小李可以打開C頁面虽画,可以進行ca和cb操作荣病,但是他想打開C頁面時會被提示沒有權(quán)限,他嘗試直接通過URL繞過頁面進行aa操作脖岛,通用也會被提示沒有權(quán)限
設(shè)計的表結(jié)構(gòu)
-- 訪問權(quán)限表
CREATE TABLE `auth_access` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL COMMENT '權(quán)限名稱',
`value` varchar(255) NOT NULL DEFAULT '' COMMENT '權(quán)限值',
`type` char(1) NOT NULL DEFAULT 'U' COMMENT '資源類型柴梆,默認為URL(''U'')',
`comment` varchar(255) NOT NULL DEFAULT '' COMMENT '備注',
`disable` tinyint(4) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
-- 角色表
CREATE TABLE `auth_role` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色ID',
`pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID终惑,為0時為頂級',
`comment` varchar(255) NOT NULL DEFAULT '' COMMENT '備注',
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加時間 ',
`orderNo` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '排序,越大越靠前',
`name` varchar(64) NOT NULL,
`disable` tinyint(255) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
-- 角色權(quán)限表
CREATE TABLE `auth_rel_role_access` (
`rid` int(10) unsigned NOT NULL COMMENT 'role id',
`aid` int(10) unsigned NOT NULL COMMENT 'access id',
PRIMARY KEY (`rid`,`aid`),
KEY `role_auth2` (`aid`),
CONSTRAINT `aid` FOREIGN KEY (`aid`) REFERENCES `l_auth_access` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `rid` FOREIGN KEY (`rid`) REFERENCES `l_auth_role` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 用戶角色表
CREATE TABLE `l_auth_rel_user_role` (
`uid` int(10) unsigned NOT NULL COMMENT 'user id',
`rid` int(10) unsigned NOT NULL COMMENT 'role id',
PRIMARY KEY (`uid`,`rid`),
KEY `rel_member_role2` (`rid`),
KEY `mid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
要獲取某個用戶的所有權(quán)限值L
SELECT a.id,a.name,a.value,a.type,`disable`,IFNULL(b.role_id,0) role_id,IFNULL(b.auth_id,0) authed FROM auth_access a
LEFT JOIN (
SELECT rmr.rid AS role_id, rra.aid AS auth_id
FROM auth_rel_user_role rmr
INNER JOIN auth_role r on r.id = rmr.rid and r.`disable` = 0
INNER JOIN auth_rel_role_access rra ON rra.rid = rmr.rid
WHERE rmr.uid = :user_id
) b ON b.auth_id = a.id;
如果用戶有訪問權(quán)限揣苏,authed > 0卸察;否則 authed = 0
獲取某個用戶所有的角色
select r.*,IFNULL(rr.rid,0) as roled
from role r
left outer join rel_user_role rr on rr.rid = r.id and rr.uid = :user_id
如果用戶有該角色铅祸,roled > 0合武;否則 roled = 0
獲得某個角色所有的權(quán)限
select a.*,ifnull(rra.aid,0) as accessable from access a
left outer join rel_role_access rra on rra.aid = a.id and rra.rid = :role_id
如果用戶有該角色稼跳,accessable > 0;否則 accessable = 0
如果你不需要未授權(quán)的部分汤善,以上的查詢sql只要講left outer join 改為 inner join,ifnull函數(shù)也可以去掉