前端权限的控制思路
1.菜单控制
2.界面控制
3.按钮控制
4.请求和响应控制
1.菜单控制
可以直接映射vuex里state里面的数据,使用方式:
//组件页面使用vuex里面的数据
import {mapState} from 'vuex'
//计算属性映射state数据
computed:{
...mapState(['list'])
},
//页面初始化的时候使用数据
created(){
this.arrlist = this.list
}
//https://vuex.vuejs.org/zh/guide/state.html#mapstate-%E8%BE%85%E5%8A%A9%E5%87%BD%E6%95%B0
小结:
- 权限的数据需要在多组件之间共享,要采用vuex
- 防止刷新界面,权限数据丢失,所以需要存储在会话存储里面,并且要保证两者同步
2.界面控制
思路:通过登录界面,登录成功之后跳转到管理平台界面,但是用户直接敲入管理平台的地址,也是可以跳过登录的步骤,所以应该在前置路由守卫里面去判断用户跳转界面
1)如果直接就去登录界面 – 放行;
2)如果直接去的不是登录界面,则判断是否存在Token,如果token不存在,就直接跳转到登录页面;如果token存在,则直接放行
路由规则动态添加:
在router.js里面导出一个方法
//router.js文件中
export function initDynamicRoutes(){
//根据二级权限,对路由规则进行动态添加
const currentRoutes = router.options.routes
currentRoutes[2].children.push({'路由对象'})
router.addRoutes(currentRoutes)
}
//在登录页面登录成功之后被调用
//注意:页面刷新以后,路由页面会重新加载,解决办法,在App.vue里面导入上面的方法,然后再created生命周期里面调用
小结:
- 路由的导航守卫可以防止跳过登录界面
- 动态路由可以让不具备权限的界面的路由规则不存在
3.按钮控制 – 自定义指令
//其他页面使用自定义指令
<el-button type="primary" v-permission="{action:'add',effect:'disabled'}">添加用户</el-button>
//permission.js
import Vue from 'vue'
import router from '@/router.js'
Vue.directive('permission',{
inserted(el,binding){
const action = binding.value.action
const effect = binding.value.effect
//判断,当前的路由所对应的组件中,如何判断用户是否具备action的权限
if(router.currentRoute.meta.indexOf(action) == -1){
if(effect === 'disabled'){
el.disabled = true
//以下是elementui的要求
el.classList.add('is-disabled')
}else{
el.parentNode.removeChild(el)
}
}
}
})
小结:
- 路由规则中可以增加路由元数据meta
- 通过路由对象可以得到当前的路由规则以及存储在此规则中的Meta数据
- 自定义指令可以很方便的实现按钮权限控制
4.请求和响应控制
axios官方文档:https://www.axios-http.cn/docs/intro
//http.js页面
import axios from 'axios'
import Vue from 'vue'
import router from '@/router.js'
const actionMapping = {
'get':'view',
'post':'add',
'put':'edit',
'delete':'delete'
}
//配置请求的根路径
axios.defaults.baseURL = 'http://localhost:8080/api/private/v1/'
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
if(config.url !== 'login'){
//不是登录的请求,我们应该在请求头中加入token数据
config.headers.Authorization = sessionStorage.getItem('token')
const action = actionMapping[config.method]
//判断非权限范围内的请求
const currentRight = router.currentRoute.meta
if(currentRight && currentRight.indexOf(action) === -1){
//没有权限
alert('没有权限')
return Promise.reject(new Error('没有权限'))
}
//判断当前请求的行为,可以根据请求方式判断要做的事情
//restful风格请求
//get 请求 view
//post请求 add
//put请求 edit
//delete请求 delete
}
return config;
});
// 添加响应拦截器
//得到了服务器返回的状态码401,代表token超时或者被篡改了,此时应该强制跳转到登录界面
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
if(response.data.meta.status === 401){
router.push('/login')
sessionStorage.clear()
window.location.reload()
}
return response;
});
Vue.prototype.$http = axios
小结:
- 请求拦截器和响应拦截器的使用
- 请求方式的约定restful