RBAC 是基于角色的访问控制 Role-Based Access Control

1. 菜单的控制

在登录请求中会得到权限数据, 这个需要后端返回数据的支持。
前端根据权限数据, 展示对应的菜单。

  1. {
  2. id: 2,
  3. username: '管理员',
  4. password: 'admin',
  5. token: 'abcdefghijklmnopqrstuvwxyz'.split('').reverse().join(''),
  6. rights: [{
  7. id: 1,
  8. authName: '一级菜单',
  9. icon: 'icon-menu',
  10. children: [{
  11. id: 11,
  12. authName: '一级项目1',
  13. path: '/menu/one',
  14. rights: ['view', 'edit', 'add', 'delete']
  15. }, {
  16. id: 11,
  17. authName: '一级项目2',
  18. path: '/menu/two',
  19. rights: ['view', 'edit', 'add', 'delete']
  20. }]
  21. }
  22. ...

用户登录之后服务端返回一个数据,这个数据有菜单列表和token,我们把这个数据放入到vuex中,然后主页根据vuex中的数据进行菜单列表的渲染

问题: 刷新界面vuex数据消失,菜单栏消失

解决: 在vuex中的 mutations 将数据存储在 sessionStorage 中,并让其和 vuex 中的数据保持同步
image.png
退出的时候记得删除数据

  1. sessionStorage.clear()
  2. this.$router.push('/login')
  3. window.location.reload()

2.界面的控制

如果用户没有登录, 手动在地址栏敲入管理界面的地址, 则需要跳转到登录界面
如果用户已经登录, 如果手动敲入非权限内的地址, 则需要跳转404 界面

1. 路由导航守卫

登录成功后,将token数据存储在sessionStorage中,判断是否登录
image.png
问题: 这样用户在登录之后就可以访问其他界面了,但如果用户A登录之后他只能访问a页面,他不能访问b页面,但是这时候他还是可以通过地址栏输入进入到b页面

解决: 当然我们也可以设置路由导航守卫,但是如果有多个页面,设置会非常不方便,并且对于用户A来说,它是不用访问b页面的,这时候我们何不对A不显示b页面,这个时候我们就用到了动态路由

2. 动态路由

登录之后,根据当前用户所拥有的的权限数据来动态添加所需要的路由

  1. 先定义好所有的路由规则
    image.png
  2. 登录成功之后动态添加路由,注意这个initDynamicRoutes的方法需要暴露出去在登录后调用
    image.png

问题: 如果我们重新刷新的话动态路由就会消失,动态路由是在登录成功之后才会调用的,刷新的时候并没有调用,所以动态路由没有添加上。

解决: 可以在app.vue中的created中调用添加动态路由的方法

3.按钮的控制

在某个菜单的界面中, 还得根据权限数据, 展示出可进行操作的按钮,比如删除, 修改, 增加

比如我们可以根据后端返回的数据right来判断用户有什么权限,如下图
image.png

添加自定义指令 控制按钮
image.png

4.请求和响应的控制

如果用户通过非常规操作, 比如通过浏览器调试工具将某些禁用的按钮变成启用状态, 此时发的请求也应该被前端所拦截

  • 除了登录请求都得要带上token , 这样服务器才可以鉴别你的身份这块使用的就是asiox的请求拦截器设置
    image.png

如果发出了非权限内的请求, 应该直接在前端范围内阻止, 虽然这个请求发到服务器也会被拒绝

非权限内的请求:比如a用户是不能够操作该页面的按钮的,但是他通过f12调试把按钮改为可点击,如果我们不对这个请求进行处理,那么这个请求就会发送出去

image.png

响应控制

得到了服务器返回的状态码401, 代表token 超时或者被篡改了,此时应该强制跳转到登录界面
image.png

小结

前端权限的实现之须要后端提供数据支持, 否则无法实现。
返回的权限数据的结构, 前后端需要沟通协商怎样的数据便用起来才最方便

  • 菜单控制
    • 权限的数据需要在多组件之间共享, 因此采用vuex
    • 防止刷新界面, 权限数据丢失, 所以需要存在sessionStorage, 并目要保证两者的同步
  • 界面控制
    • 路由的导航守卫可以防止跳过登录界面
    • 动态路由可以让不具备权限的界面的路由规则压根就不存在
  • 按钮控制
    • 路由规则中可以增加路由元数据meta
    • 通过路由对象可以得到当前的路由规则以及存在此规则中的meta 数据
    • 自定义指令可以很方便的实现按钮控制
  • 请求和响应控制
    • 请求拦截器和响应拦截器的使用

https://blog.csdn.net/weixin_44157964/article/details/108420759

https://www.bilibili.com/video/BV15Q4y1K79c