在实际的软件项目开发过程中,用户权限控制可以说是所有运营系统中必不可少的一个重点功能,根据业务的复杂度,设计的时候可深可浅,但无论怎么变化,设计的思路基本都是围绕着用户、角色、菜单这三个部分展开。
如何设计一套可以精确到按钮级别的用户权限功能呢?
今天通过这篇文章一起来了解一下相关的实现逻辑,不多说了,直接上案例代码!
01、数据库设计
在进入项目开发之前,首先我们需要进行相关的数据库设计,以便能存储相关的业务数据。
对于【用户权限控制】功能,通常5张表基本就可以搞定,分别是:用户表、角色表、用户角色表、菜单表、角色菜单表,相关表结构示例如下。
其中,用户和角色是多对多的关系,角色与菜单也是多对多的关系,用户通过角色来关联到菜单,当然也有的用户权限控制模型中,直接通过用户关联到菜单,实现用户对某个菜单权限独有控制,这都不是问题,可以自由灵活扩展。
用户、角色表的结构设计,比较简单。下面,我们重点来解读一下菜单表的设计,如下:
可以看到,整个菜单表就是一个父子表结构,关键字段如下:
- name:菜单名称
- menu_code:菜单编码,用于后端权限控制
- parent_id:菜单父节点ID,方便递归遍历菜单
- node_type:菜单节点类型,可以是文件夹、页面或者按钮类型
- link_url:菜单对应的地址,如果是文件夹或者按钮类型,可以为空
- level:菜单树的层次,以便于查询指定层级的菜单
- path:树id的路径,主要用于存放从根节点到当前树的父节点的路径,想要找父节点时会特别快
为了方便项目后续开发,在此我们创建一个名为menu_auth_db
的数据库,SQL 初始脚本如下:
02、项目构建
菜单权限模块的数据库设计搞定之后,就可以正式进入系统开发阶段了。
2.1、创建项目
为了快速构建项目,这里采用的是springboot
+mybatisPlus
框架来快速开发,借助mybatisPlus
提供的生成代码器,可以一键生成所需的dao
、service
、web
层的服务代码,以便帮助我们剩去 CRUD 中重复编程的工作量,内容如下:
CRUD 代码生成完成之后,此时我们就可以编写业务逻辑代码了,相关示例如下!
2.2、菜单功能开发
2.2.1、菜单新增逻辑示例
2.2.2、菜单查询逻辑示例
这里需要用到递归算法来封装菜单视图。
为了便于演示,这里我们先在数据库中初始化几条数据,最后三条数据指的是按钮类型的菜单,用户真正请求的时候,实际上请求的是这三个功能,内容如下:
对queryMenuTree
接口发起请求,返回的数据结果如下图:
将返回的数据,通过页面进行渲染之后,结果类似如下图:
2.3、用户权限开发
在上文,我们提到了用户通过角色来关联菜单,因此,很容易想到,用户控制菜单的流程如下:
- 第一步:用户登陆系统之后,查询当前用户拥有哪些角色;
- 第二步:再通过角色查询关联的菜单权限点;
- 第三步:最后将用户拥有的角色名下所有的菜单权限点,封装起来返回给用户;
带着这个思路,我们一起来看看具体的实现过程。
2.3.1、用户权限点查询逻辑示例
2.4、用户鉴权开发
完成以上的逻辑开发之后,可以实现哪些用户拥有哪些菜单权限点的操作,比如用户【张三】,拥有【用户管理】菜单,那么他只能看到【用户管理】的界面;用户【李四】,用于【角色管理】菜单,同样的,他只能看到【角色管理】的界面,无法看到其他的界面。
但是某些技术人员发生漏洞之后,可能会绕过页面展示逻辑,直接对接口服务发起请求,依然能正常操作,例如利用用户【张三】的账户,操作【角色管理】的数据,这个时候就会发生数据安全隐患的问题。
为此,我们还需要一套用户鉴权的功能,对接口请求进行验证,只有满足要求的才能获取数据。
其中上文提到的菜单编码menuCode
就是一个前、后端联系的桥梁。其实所有后端的接口,与前端对应的都是按钮操作,因此我们可以以按钮
为基准,实现前后端双向权限控制。
以【角色管理-查询】这个为例,前端可以通过菜单编码实现是否展示这个查询按钮,后端可以通过菜单编码来鉴权当前用户是否具备请求接口的权限,实现过程如下!
2.4.1、权限控制逻辑示例
在此,我们采用权限注解
+代理拦截器
的方式,来实现接口权限的安全验证。
2.4.2、鉴权逻辑验证
我们以上文说到的【角色管理-查询】为例,编写一个服务接口来验证一下逻辑的正确性。
首先,编写一个请求实体类RoleDTO
,添加userId
属性
其次,编写一个角色查询接口,并在方法上添加@CheckPermissions
注解,表示此方法需要鉴权,满足条件的用户才能请求通过。
最后,在数据库中初始化相关的数据。例如给用户【张三】分配一个【访客人员】角色,同时这个角色只有【系统配置】、【用户管理】菜单权限。
启动项目,在postman
中传入用户【张三】的ID,查询用户具备的菜单权限,只有两个,结果如下:
同时,利用用户【张三】发起【角色管理-查询】操作,提示:接口无访问权限,结果如下:
与预期结果一致!因为没有配置角色查询接口,所以无权访问!
03、小结
最后总结一下,【用户权限控制】功能在实际的软件系统中非常常见,希望本篇的知识能帮助到大家。
此外,想要获取项目源代码的小伙伴,可以关注下方公众号并回复:用户权限控制,即可获取取项目的源代码。
04、写到最后
不会有人刷到这里还想白嫖吧?点赞对我真的非常重要!在线求赞。加个关注我会非常感激!
此外,本文已整理到技术笔记中,笔记内容还涵盖 Spring、Spring Boot/Cloud、Dubbo、JVM、集合、多线程、JPA、MyBatis、MySQL 等技术知识。需要的小伙伴可以点击 技术笔记 获取!