1 前端权限控制思路
1.1菜单的控制
在登录请求中,会得到权限数据。前端根据权限数据,展示对应的菜单,点击菜单,才能查看相关的界面
1.2界面的控制
如果用户没有登录,手动在地址栏敲入管理界面的地址,则需要跳转到登录界面
如果用户已经登录,可是手动敲入非权限内的地址,则需要跳转到404界面
1.3按钮的控制
在某个菜单的界面中,还得根据权限数据,展示出可进行操作的按钮,比如删除,修改,增加
1.4请求和响应控制
如果用户通过非常规操作,比如通过浏览器调试工具将某些禁用的按钮变成开启状态,此时发的请求,也应该被前端所拦截
2 Vue的权限控制实现
2.1 菜单的控制
我们点击登录按钮,登陆成功之后,后端除了用户的基本信息外,还有token数据,用于前端用户的状态保持,还会返回用户的权限数据。如下图的对象中的rights数组就是后端返回的权限数据,根据这个权限数据渲染不同的菜单,有一级菜单和二级菜单,可以通过v-for渲染,这个数据可以保存在store中,这样就可以在组件中共享了。
但是这样有一个问题,因为要用于渲染菜单的数据存储在store中,当登陆成功之后如果点击了刷新页面,vuex会重新加载,存放数据的数组会变成空数组,这样的话用于渲染菜单的数据就会丢失,菜单就会渲染不出来
- 刷新界面菜单消失
因为菜单数据是登录之后才获取到的,获取菜单数据之后,就存放在vuex中
一旦刷新界面,Vuex中的数据会重新初始化,所以就会变成空的数组
因此,需要将权限数据存储在sessionStorage中,并让其和vuex中的数据保持同步
解决办法:
这样的话虽然刷新页面Vuex会初始化,但是权限数据列表的初始值会从sessionStorage中获取
注意:要用||做一个判断防止不存在报错
这样如果点击退出按钮退出的话,需要清除用户数据
先清除sessionStorage中的数据,然后通过lwindow.location.reload()刷新页面清空store中的数据
2.2 界面的控制
1 正常的逻辑是通过登录界面,登录成功之后跳转到管理平台界面,但是如果用户直接敲入管理平台的地址,也是可以跳过登录的步骤,所以应该在某个时机判断用户是否登录
- 如何判断是否登录
登录的时候要存储token数据
sessionStorage.setItem('token', res.data.token)
- 什么时机
-
- 路由导航守卫
在router.js文件中
每次路由变化的时候进行监听,to代表去哪一个页面,from代表从哪一个页面来,next是放行函数
router.beforeEach((to, from, next) => {
if (to.path === '/login') {
// 访问登录界面,直接放行
next()
} else {
// 访问非登录界面,需要验证是否有token
const token = sessionStorage.getItem('token')
if (!token) {
next('login')
} else {
next()
}
}
})
2 虽然菜单项已经被控制住了,但是路由信息还是完整的存在于浏览器,正比如一个用户并不具备角色这个菜单,但是他如果在地址栏中敲入/roles的地址,依然可以访问角色界面
- 路由导航守卫
路由导航守卫固然可以在每次路由地址发生变化的时候,从vuex中取出权限数据rightlist判断用户将要访问的界面,这个用户到底有没有权限,不过从另外一个角度来说,这个角色不具备权限的路由,是否也应该压根不存在呢? - 动态路由
-
- 登录成功之后动态添加
-
- APP.vue中添加
-
- 代码如下
在router.js中export一个方法用于动态添加路由,通过循环权限数据,然后在router的路由规则routes中添加该用户权限应有的路由信息
- 代码如下
在登录成功的时候调用router.js中的这个方法
如果找不到这个页面的话就会被404页面匹配到
但是有一个大bug,就是刷新页面的时候,router.js文件会重新加载,那样的话动态路由就会消失,解决办法是在App.vue文件中的created方法中执行添加动态路由方法
2.3 按钮的控制
按钮控制
虽然用户可以看到某些界面了,但是这个界面的一些按钮,该用户可能是没有权限的,因此,我们需要对组件中的一些按钮进行控制,用户不具备权限的按钮就隐藏或者禁用,而这块中,可以把该逻辑放到自定义指令中
可以参考vue自定义指令
链接
1 在permission.js文件中定义指令
2 在按钮上使用自定义指令
2.4 请求和响应的控制
请求控制
-
除了登录请求都得要带上token,这样服务器才可以鉴别你的身份
在封装axios的文件中的请求拦截器中加上token
-
如果发出了非权限内的请求,应该直接在前端访问内阻止,虽然这个请求发送到服务器也会被拒绝
响应控制 -
得到了服务器返回的状态码401,代表token超时或者被篡改了,此时应该强制跳转到登录界面
小结
1 菜单控制
- 权限的数据需要在多组件之间共享,因此采用vuex
- 防止刷新界面,权限数据丢失,所以需要存储在sessionStorage,并且要保证两者的同步
2 界面控制
- 路由的导航守卫可以防止跳过登录界面
- 动态路由可以让不具备权限的界面的路由规则压根不存在
3 按钮控制
- 路由规则中可以增加路由元数据meta
- 通过路由对象可以得到当前的路由规则,以及存储在此规则中的meta数据
- 自定义指令可以很方便的是心啊按钮控制
4 请求和响应控制
- 请求拦截器和响应拦截器的使用
- 请求方式的约定restful