深度解析RBAC用户-角色-权限设计方案,以及核心逻辑代码的讲解
Posted Roninaxious
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度解析RBAC用户-角色-权限设计方案,以及核心逻辑代码的讲解相关的知识,希望对你有一定的参考价值。
首先对于b2b、b2c等这一些网站后台,一般情况下都需要权限管理的设计与实现,对于这部分,通常是固定不变的,每次只需要做少量的改动即可。
如何设计这几张表呢?
RBAC(基于角色的访问控制),也就是用户通过角色与权限进行关联;一个角色拥有多个角色,一个角色拥有多个权限;这样就构成了下图中的用户-角色-权限的授权模型;
用户与角色之间、角色与权限之间一般是多对多的关系。对于一对多关系表的设计中,我们一般是多的那一方多加入一个字段即可;而对于多对多关系表的设计,一般来说我们要借助第三方表
这五张表是至少的,也就是说权限的设计要>=5张表,具体需要多少张表还需要根据系统业务做相应的增加。
从上图中我们可以观察出,权限表与角色表通过role_permission表联系起来,在role_permission表中必要的两个字段就是权限id和角色id;当然用户表和角色表也一样。
有关核心的逻辑代码
由于一个后台系统可能包含多级菜单(权限),比如电器商品是一级菜单,电器商品删除是二级菜单等等,所以在对所有的菜单(权限)进行查询的过程中,需要进行树状显示。所以需要进行递归遍历。
@Override
public List<Permission> queryAllMenu() {
//1 查询菜单表所有数据
QueryWrapper<Permission> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
List<Permission> permissionList = baseMapper.selectList(wrapper);
//2 把查询所有菜单list集合按照要求进行封装
List<Permission> resultList = bulidPermission(permissionList);
return resultList;
}
//把返回所有菜单list集合进行封装的方法
public static List<Permission> bulidPermission(List<Permission> permissionList) {
//创建list集合,用于数据最终封装
List<Permission> finalNode = new ArrayList<>();
//把所有菜单list集合遍历,得到顶层菜单 pid=0菜单,设置level是1
for(Permission permissionNode : permissionList) {
//得到顶层菜单 pid=0菜单
if("0".equals(permissionNode.getPid())) {
//设置顶层菜单的level是1
permissionNode.setLevel(1);
//根据顶层菜单,向里面进行查询子菜单,封装到finalNode里面
finalNode.add(selectChildren(permissionNode,permissionList));
}
}
return finalNode;
}
private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {
//1 因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化
permissionNode.setChildren(new ArrayList<Permission>());
//2 遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同
for(Permission it : permissionList) {
//判断 id和pid值是否相同
if(permissionNode.getId().equals(it.getPid())) {
//把父菜单的level值+1
int level = permissionNode.getLevel()+1;
it.setLevel(level);
//如果children为空,进行初始化操作
if(permissionNode.getChildren() == null) {
permissionNode.setChildren(new ArrayList<Permission>());
}
//把查询出来的子菜单放到父菜单里面
permissionNode.getChildren().add(selectChildren(it,permissionList));
}
}
return permissionNode;
}
下面是递归删除权限的逻辑,思路是递归查询该id下的所有子权限,然后批量删除即可。
@Override
public void removeChildById(String id) {
List<String> idList = new ArrayList<>();
selectPermissionIdList(idList, id);
idList.add(id);
baseMapper.deleteBatchIds(idList);
}
private void selectPermissionIdList(List<String> idList, String id) {
QueryWrapper<Permission> wrapper = new QueryWrapper<>();
wrapper.eq("pid", id).select("id");
List<Permission> permissionList = baseMapper.selectList(wrapper);
permissionList.stream().forEach(permission -> {
idList.add(permission.getId());
this.selectPermissionIdList(idList, permission.getId());
});
}
以上是关于深度解析RBAC用户-角色-权限设计方案,以及核心逻辑代码的讲解的主要内容,如果未能解决你的问题,请参考以下文章