发布时间:2023-06-09 10:00
最近大半年的时间都在写后台内容管理系统,后台管理系统在前端的工作主要就是各种表单,表格制作。在后端的工作就是各种sql查询啦(各种报表查询属实让我脑壳疼)。后台管理系统我认为较重要的部分就是权限控制了,较为流行的模式就是基于角色的访问控制(Role-Based Access Control),简称为RBAC。
思路
前后端分离项目的权限控制在前端这边主要体现为菜单路由,以及按钮的显示控制,在后端就是对控制器、方法的访问控制,在这次实践中api采用ThinkPHP5.1开发,使用了该框架的路由功能,那么针对路由进行权限控制就可以了。 前端根据接口下发的权限信息来控制菜单(动态添加路由)以及按钮的显示,后端控制接口的访问权限,无权访问接口返回指定状态码(如:403),前端收到此状态码提示用户无权限。
前端采用vue结合elemen-ui进行开发,vue的路由表就是一个树形结构,我们直接用它生成菜单即可。既然要通过路由来控制页面的显示与否,那页面中的内容也应该是要加权限的,毕竟把权限交给前端来控制一点也不靠谱,页面中的内容(比如列表数据)都是请求后端接口来获取的,也就是说这个页面用户没有权限访问,那么这个页面中调用的接口用户也应该无权调用。接口的权限在后端检测。这样 我们在前端和后端api都加上了权限控制就没啥问题了。
总结:api接口权限和页面权限是从属关系
例子1:
a用户无权访问新闻管理界面 那么他同样无权调用新闻管理页面的接口。
做法:前端不在路由表中 动态添加 新闻管理 这个路由。 后端检测接口权限, 通过查询数据库发现获取新闻列表接口、删除新闻等接口是属于新闻管理这个界面的,那么拦截用户的请求并返回 403 状态码 提示用户没有权限调用。
例子2:
b用户有权访问新闻管理界面 但无权删除新闻。
做法:前端在路由表中 动态添加 新闻管理 这个路由,通过接口返回的权限信息 隐藏 删除新闻这个按钮。 当用户通过某种方式调用了删除新闻的api,后端检测api权限 通过查询数据库发现用户没有删除新闻的权限,那么拦截用户的请求并返回 403 状态码 提示用户没有权限调用。
权限配置流程:
根据模块或者页面划分权限->给角色分配权限->给用户分配角色
权限控制实现流程:
用户登录 ->接口验证账号信息->接口下发token->接口下发用户的信息(名称,角色,权限等)->前端根据 权限动态添加路由菜单
数据库设计
权限相关的有6张表,分别是 用户信息表 角色信息表 菜单权限表,api权限表,因为角色与权限是多对多的关系,所以还有角色与菜单权限中间表, 角色与api权限中间表。
我这里是一个用户只能有一个角色如果要做一个用户多个角色的话还需要 用户与角色中间表。
菜单权限表中的记录系统中的所有页面。因为前端vue-router的路由表本身就是树形结构,我觉得没必要在数据库中也弄一个树形结构,这样太复杂了。 我这里的方法是 遍历前端路由,将每个路由对象的 name同步到后端,菜单权限表中的menu_name就是前端路由对象的name属性。对角色的权限管理其实就是对角色与菜单权限中间表的增删查。
//这是一个vue路由对象:
{
path: '/Home',
name: 'Home',
component: () => import('../views/Home/Home'),
meta: {
title: '首页'
}
},
api权限表中记录的是所有的api权限,api权限有一个menu_name字段关联菜单权限表的menu_name字段。这样就可以确定这个api权限是属于哪个页面的。route_path字段是后端的路由,后端通过查询 角色与api权限中间表,如果请求的path所对应的权限 不在表中,就对其拦截返回403状态码。
具体实现
在权限配置页面将 前端路由同步到 数据库,点击菜单节点,可在菜单下添加修改 具体api权限:
角色信息修改界面可配置角色的菜单权限以及具体api权限:
操作员管理界面可为用户分配角色:
当操作员登录后台管理系统后,接口返回这样的权限列表,权限列表第一层是用户具有的菜单权限,菜单权限下的api数组就是该用户在该菜单下可用的权限。前端根据获得的菜单权限,路由数据中过滤出用户可用的路由,利用vue-router 动态添加路由,根据api具体权限数据可对页面中的按钮之类的进行细粒度的显示控制:
6+
1.如需转载本站原创文章,请务必注明文章出处并附上链接,非常感谢。
2.本站用于记录个人 工作、学习、生活,非商业网站,更多信息请 点击这里
“Vue+ThinkPHP5.1 实现基于角色控制权限的前后端分离后台管理系统” 有1条评论
兄弟 最近在研究前后端分离 发现没有思路 方便看下源码么 只有权限这里的也可以 感恩
邮箱 1605790906@qq.com
1+
发表评论邮箱地址不会被公开。
评论
名称
电子邮件
站点