本猿年初的时候接手了一套后台系统,这套系统对于权限刷新了我的三观(每个用户对应一个角色ROLEID,用户访问的时候根据不同的ROLEID加载不同的模板文件,OK! A角色和B角色看到的页面就不同了)
不提这梗了,本人解释下自己对最基本的RBCA的理解,虽然简单,但应对大部分公司内部系统已经足够了
一个URL通常代表着以下类型的资源:
- 一张网页(Page):打开网页可能伴随着数据的查询或修改,但这仍然是该类型资源的一部分
- 获取数据(AjaxGet):只限于查询,不会对数据造成修改等影响
- 修改数据(AjaxUpdate):通常包括增加,删除,修改
- 文件:这个暂时未考虑
RBCA模型中涉及以下几个概念:
- 用户(User) 即登录的用户本身,有一个用户ID(定义uid)
- 角色(Role) 即这个用户拥有几个身份,一个用户可以有几个角色,比如一家小公司的人事专员可能即使人事,又是客服
- 权限(Access) access英语中的含义是访问,引申为访问的资源,习惯上可以称之为权限
下面举例子:
小珍是XX公司的人事,拥有人事专员和客服两个角色
小李是XX公司的技术,拥有技术专员的角色
人事专员可以查看A页面,可以进行A页面上的aa和ab操作
客服可以查看B页面,可以进行B页面上的ba和bb操作
技术专员可以查看C页面,可以进行C页面上的ca和cb操作
那么:
小珍可以打开A页面和B页面,可以进行aa,ab,ba,bb操作,但是想打开C页面时会被提示没有权限
小李可以打开C页面,可以进行ca和cb操作,但是他想打开C页面时会被提示没有权限,他尝试直接通过URL绕过页面进行aa操作,通用也会被提示没有权限
设计的表结构
-- 访问权限表
CREATE TABLE `auth_access` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL COMMENT '权限名称',
`value` varchar(255) NOT NULL DEFAULT '' COMMENT '权限值',
`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;
-- 角色权限表
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;
要获取某个用户的所有权限值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;
如果用户有访问权限,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
获得某个角色所有的权限
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
如果你不需要未授权的部分,以上的查询sql只要讲left outer join 改为 inner join,ifnull函数也可以去掉