问题:
一个web项目整体上包括三大块内容:前端页面、后台逻辑、数据库。
目前我们在开发一个web项目时,会在页面中将所有的资源全部声明,不同的用户访问项目,只要是登录成功,看到的页面资源以及可以操作的页面资源都是相同的。但是,在实际的业务场景中,不同的用户访问登录项目后,能够看到的以及操作的页面资源应该是不同的。
怎么办?
解决:
我们来分析下页面中的资源应该分为两大部分:
①所有用户都可以操作的资源
②不同的用户效果不同的资源
这样我们在开发页面的时候,相同的资源直接在页面中声明,不同的资源应该存储到数据库中,根据用户查询对应的资源到页面中显示。比如:菜单资源、按钮资源等。
实现:
将页面资源存储到数据库中,根据用户查询对应的资源显示到页面(权限管理)。
注意:
因为我们要将页面的资源存储到数据库中,所以项目的数据库表分为两类:
①业务表,比如:用户信息表,签到签退表
②页面资源表,比如:菜单信息表,页面代码表
用户直接和权限进行关联(用户 ---> 权限):
张一(销售):分配销售对应的功能(菜单、接口、按钮)
①查看商品列表
②添加商品
张二(销售):分配销售对应的功能(菜单、接口、按钮)
①查看商品列表
②添加商品
缺点:每来一个用户都要给他分配对应的权限,如果权限特别多,容易出错。而且如果将来有一天,我要收回这个权限,比如,所有的销售都不能添加商品,就需要找到所有的销售,把每个销售添加商品的权限都收回,特别麻烦。
RBAC权限模型(用户 -->角色--->权限):
用户:
张一:
销售
张二:
客服
张三:
①销售
②客服
角色:
销售:
①查看商品列表
②添加商品
客服:
接电话
权限:
①添加xxx
②删除xxx
③首页菜单
④删除商品按钮
优点:如果新来一个用户,我想要给他分配销售的权限,就不需要挨着挨着把销售的每一个权限都直接分配给他,而是给他分配一个销售的角色就可以了。如果有一天,我需要删除销售添加商品的权限,就只需要找到销售这个角色,在这个角色里面删除添加商品的权限就可以了,而不需要找到每一个销售用户,并且把他添加商品的权限删除。
RBAC(Role-Based Access Control):基于角色的权限访问控制。是一种数据库设计思想,根据设计数据库设计方案,完成项目的权限控制。
在RBAC中,最重要的概念包括:用户(User)、角色(Role)、权限(Permission)。
权限:具备操作某个事务的能力
角色:一系列权限的集合
用户和权限是多对多的关系。
优点:简化了用户和权限的关系、易于扩展和维护、方便统一管理
学习RBAC需要掌握的要素:
①如何设计数据库中的表
②如何根据数据库完成项目
③RBAC核心是角色,在数据库设计时,一定要有角色
④根据RBAC设计思想,设计出来的方案是非常灵活的
需求实现方案一:
传统方案,没有使用RBAC思想:
缺点:
①新建一个用户时,在用户表中添加一条数据
②新建一个用户时,在关联表中添加N条数据
③每次新建一个用户需要添加:1+N(关联几个) 条数据
需求实现方案二:
1、基于RBAC的设计方案
1)设定好在某些情况下哪些菜单需要被关联(设计角色和权限的关联)。比如:管理员可以看到所有菜单、销售总监可以看到“销售管理”菜单、普通员工只能看见系统公告。
2)现实生活中的职位,对应1个或者多个数据库中的角色
2、在系统上线后,会在程序中添加几种比较常见的角色,并把菜单和角色关联
1)以后每次新建用户时
2)在用户表中添加一个数据
3)在用户和角色关联表中添加1条或者n条数据
RBAC具体实现:
1、实现需求
使用RBAC数据库设计思想,让不同的用户登录系统后,显示不同的菜单。
2、功能分析
用户:张三和李四
菜单:
1)用户管理
①用户查询
②增加用户
2)班级管理
①班级查询
②增加班级
3)系统设置
查看公告
3、设计数据库
##创建用户信息表
create table t_user(
uid int(10) not null auto_increment,
uname varchar(100) not null,
pwd varchar(100) not null,
rid int(10),
primary key(uid)
);
##创建角色信息表
create table t_role(
rid int(10) not null auto_increment,
rname varchar(100) not null,
rdesc varchar(300),
primary key(rid)
);
##创建菜单信息表(权限表的一种)
create table t_menu(
mid int(10) not null auto_increment,
mname varchar(100) not null,
murl varchar(300),
parentid int(10) not null,
mdesc varchar(300),
primary key(mid)
);
##创建角色菜单中间表
create table r_menu(
rid int(10) not null,
mid int(10) not null
);
##添加测试数据
##添加用户测试数据
insert into t_user values(default,'张三','123',1);
insert into t_user values(default,'李四','123',2);
##添加角色测试数据
insert into t_role values(default,'管理员','具备所有的操作权限');
insert into t_role values(default,'人事经理','具备用户管理的相关权限');
##添加菜单测试数据
insert into t_menu values(default,'用户管理','',0,'一级菜单');
insert into t_menu values(default,'用户查询','',1,'二级菜单');
insert into t_menu values(default,'增加用户','',1,'二级菜单');
insert into t_menu values(default,'班级管理','',0,'一级菜单');
insert into t_menu values(default,'班级查询','',1,'二级菜单');
insert into t_menu values(default,'增加班级','',1,'二级菜单');
insert into t_menu values(default,'系统设置','',0,'一级菜单');
insert into t_menu values(default,'查看公告','',1,'二级菜单');
##添加角色菜单关联测试数据
insert into r_menu values(1,1);
insert into r_menu values(1,2);
insert into r_menu values(1,3);
insert into r_menu values(1,4);
insert into r_menu values(1,5);
insert into r_menu values(1,6);
insert into r_menu values(1,7);
insert into r_menu values(1,8);
insert into r_menu values(2,1);
insert into r_menu values(2,2);
insert into r_menu values(2,3);
用户表:
角色表:
实际上用户和角色是多对多的关系,只不过这里数据比较少,用的一对一。
菜单表(权限的一种):
角色和菜单的关系表: