中后台的管理系统权限控制是非常重要的,个人觉得 就是核心了 富文本编辑器 和一些表格导出功能算是页面级的难度吧,下面分享我收藏的关于权限控制的一些观点。
企业级中后台权限控制(vue)
注:资料参考自B站公开课
在Web系统中, 权限很久以来⼀直都只是后端程序所控制的.为什么呢? 因为Web系统的本质围绕的是数据, ⽽和数据库最紧密接触的是后端程序.所以在很⻓的⼀段时间内, 权限⼀直都只是后端程序需要考虑的话题.但是随着前后端分离架构的流⾏, 越来越多的项⽬也在前端进⾏权限控制.
1.权限相关概念
1.1.权限的分类
后端权限
从根本上讲前端仅仅只是视图层的展示, 权限的核⼼是在于服务器中的数据变化, 所以后端才是权限的关键, 后端权限可以控制某个⽤户是否能够查询数据, 是否能够修改数据等操作后端如何知道该请求是哪个⽤户发过来的后端的权限设计RBAC
前端权限
前端权限的控制本质上来说, 就是控制前端的 视图层的展示和前端所发送的请求. 但是只有前端权限控制没有后端权限控制是万万不可的. 前端权限控制只可以说是达到锦上添花的效果.
1.2.前端权限的意义
如果仅从能够修改服务器中数据库中的数据层⾯上讲,确实只在后端做控制就⾜够了, 那为什么越来越多的项⽬也进⾏了前端权限的控制, 主要有这⼏⽅⾯的好处降低⾮法操作的可能性不怕贼偷就怕贼惦记, 在⻚⾯中展示出⼀个 就算点击了也最终会失败 的按钮, 势必会增加有⼼者⾮法操作的可能性
尽可能排除不必要请求,减轻服务器压⼒ 没必要的请求, 操作失败的请求, 不具备权限的请求, 应该压根就不需要发送,请求少了, ⾃然也会减轻服务器的压⼒ 提⾼⽤户体验
Cookie,session,token
⽤户
⻆⾊
权限
根据⽤户具备的权限为该⽤户展现⾃⼰权限范围内的内容,避免在界⾯上给⽤户带来困扰, 让⽤户专注于分内之事
2.前端权限控制思路
2.1.菜单的控制
在登录请求中, 会得到权限数据, 当然, 这个需要后端返回数据的⽀持. 前端根据权限数据, 展示对应的菜单.点击菜单,才能查看相关的界⾯.
2.2.界⾯的控制
如果⽤户没有登录,⼿动在地址栏敲⼊管理界⾯的地址, 则需要跳转到登录界⾯如果⽤户已经登录, 可是⼿动敲⼊⾮权限内的地址,则需要跳转404界⾯
2.3.按钮的控制
在某个菜单的界⾯中, 还得根据权限数据, 展示出可进⾏操作的按钮, ⽐如删除,修改,增加
2.4.请求和响应的控制
如果⽤户通过⾮常规操作, ⽐如通过浏览器调试⼯具将某些禁⽤的按钮变成启⽤状态, 此时发的请求, 也应该被前端所拦截
3. Vue的权限控制实现
3.1.菜单的控制
查看登录之后获取到的数据
{
"data": {
"id": 500,
"rid": 0,
"username": "admin",
"mobile": "13999999999",
"email": "123999@",
"token": "Bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjUwMCwicmlkIjowLCJpYXQiOjE1M
-
tPsO9r_pxHIQ5i5L1kX9RX444uwnRGaIM"
},
"rights": [{
"id": 125,
"authName": "⽤户管理",
"icon": "icon-user",
"children": [{
"id": 110,
"authName": "⽤户列表",
"path": "users",
在这部分数据中, 除了该⽤户的基本信息之外, 还有两个字段很关键token,⽤于前端⽤户的状态保持rights:该⽤户具备的权限数据,⼀级权限就对应⼀级菜单,⼆级权限就对应⼆级菜单,根据rights中的数据, 动态渲染左侧菜单栏, 数据在得到, 但是在才使⽤, 所以可以把数据⽤vuex进⾏维护 vuex中的代码
"rights": ["view", "edit", "add", "delete"]
}]
}, {
"id": 103,
"authName": "⻆⾊管理",
"icon": "icon-tijikongjian",
"children": [{
"id": 111,
"authName": "⻆⾊列表",
"path": "roles",
"rights": ["view", "edit", "add", "delete"]
}]
}, {
"id": 101,
"authName": "商品管理",
"icon": "icon-shangpin",
"children": [{
"id": 104,
"authName": "商品列表",
"path": "goods",
"rights": ["view", "edit", "add", "delete"]
}, {
"id": 121,"authName": "商品分类","path": "categories","rights": ["view", "edit", "add", "delete"]
}]
}],
"meta": {"msg": "登录成功","status": 200}
}
export default new ({
state: {
rightList:[]
},
mutations: {
setRightList(state, data) {
= data
因为菜单数据是登录之后才获取到的, 获取菜单数据之后,就存放在Vuex中⼀旦刷新界⾯, Vuex中的数据会重新初始化, 所以会变成空的数组 因此, 需要将权限数据存储在sessionStorage中, 并让其和Vuex中的数据保持同步
},
退出按钮的逻辑
3.2.界⾯的控制
1.正常的逻辑是通过登录界⾯, 登录成功之后跳转到管理平台界⾯, 但是如果⽤户直接敲⼊管理平台的地址, 也是可以跳过登录的步骤.所以应该在某个时机判断⽤户是否登录如判断是否登录 什么时机 使用路由导航守卫
2.虽然菜单项已经被控制住了, 但是路由信息还是完整的存在于浏览器,正⽐如zhangsan这个⽤户并不具备⻆⾊这个菜单, 但是他如果⾃⼰在地址栏中敲⼊/roles的地址, 依然也可以问⻆⾊界⾯路由导航守卫路由导航守卫固然可以在每次路由地址发⽣变化的时候, 从vuex中取出rightList判断⽤户将要访问的界⾯, 这个⽤户到底有没有权限.不过从另外⼀个⻆度来说,这个⽤户不具备权限的路由, 是否也应该压根就不存在呢?
动态路由 登录成功之后动态添加
3.3.按钮的控制
按钮控制
虽然⽤户可以看到某些界⾯了, 但是这个界⾯的⼀些按钮,该⽤户可能是没有权限的.因此, 我们需要对组件中的⼀些按钮进⾏控制. ⽤户不具备权限的按钮就隐藏或者禁⽤, ⽽在这块中, 可以把该逻辑放到⾃定义指令中
3.4.请求和响应的控制
请求控制
除了登录请求都得要带上token, 这样服务器才可以鉴别你的身份如果发出了⾮权限内的请求, 应该直接在前端访问内组织,虽然这个请求发到服务器也会被拒绝响应控制得到了服务器返回的状态码401, 代表token超时或者被篡改了, 此时应该强制跳转到登录界⾯
4.⼩结
前端权限的实现必须要后端提供数据⽀持, 否则⽆法实现.返回的权限数据的结构,前后端需要沟通协商, 怎样的数据使⽤起来才最⽅便.
// 当前模块中具备的权限
// 查看 get请求
// 增加 post请求
// 修改 put请求
// 删除 delete请求
// 根据请求, 得到是哪种操作
// 判断action是否存在当前路由的权限中
// 没有权限
4.1.菜单控制
权限的数据需要在多组件之间共享, 因此采⽤vuex 防⽌刷新界⾯,权限数据丢失, 所以需要存储在sessionStorage, 并且要保证两者的同步
4.2.界⾯控制
路由的导航守卫可以防⽌跳过登录界⾯动态路由可以让不具备权限的界⾯的路由规则压根就不存在
4.3.按钮控制
路由规则中可以增加路由元数据meta通过路由对象可以得到当前的路由规则,以及存储在此规则中的meta数据⾃定义指令可以很⽅便的实现按钮控制
4.4.请求和响应控制
请求拦截器和响应拦截器的使⽤
请求⽅式的约定restful