什么叫权限
权限是对特定资源的访问许可,所谓的权限控制,也就是确保用户只能访问到被分配的资源。
前端权限归根结底是请求的发起权,请求的发起一般有下面两种情况:
- 页面加载时触发
- 点击页面上的按钮触发 总的来说,所有的请求发起都触发自前端路由或视图
前端权限控制可以分为四个方面:
- 接口权限
- 按钮权限
- 菜单权限
- 路由权限 今天,我们主要来看一看接口权限
一,接口权限
当用户需要访问数据发送请求时,通常都得获取token密匙,只有通过token的验证,用户才能访问页面,若是没有token或者token失效,都会跳转登陆页进行重新获取,并在控制台打印401错误。
因为用户的token都是在登录的时候获取,所在登录页和注册页访问接口数据时,不需要token值,并且在用户点击登录时从接口获取token值保存在本地中。
如果项目较大,需要用到vuex,建议将token值存放在vuex中,代码如下:
01,定义函数发送请求
actions: {
//用户点击登录 获取token值
async userLogin(context,token){
const res = await login(token)
// console.log(res)
context.commit('setToken',res.data)
},}
02,获取token并储存到state中
mutations: {
// 获取token值
setToken(state,newToken){
state.token = newToken
}
03,定义空token,接收token值并储存
state:()=>{
return {
//保存token
token: '',
}
},
04,登录页调用userLogin函数并传参,参数为用户账号与密码,注释部分为直接在登录页获取token
async dologin(){
try{
await this.$store.dispatch('user/userLogin',this.loginForm)
// const res = await login(this.loginForm)
// // console.log(res.data)
// // 将token值传给mutations
// //前面记得加模块名user
// this.$store.commit('user/setToken',res.data)
const return_url = this.$route.query.return_url || ''
this.$router.push(return_url)
}catch(err){
alert(err)
}
},
注意:在登录页加async和await,是为了让登录页dologin里面的代码同步执行,如果不加,代码运行时不会等待调用actions里面的函数传值回来
另外,以上代码只是获取了token,页面一刷新,token就没了,所以我们需要将token保存在本地,有三种方法可以实现:
- 使用本地存储来实现
localStorage.setItem('token',res.token)//储存
// 存储共享数据的对象,取出在保存
state: {
// 存储token值
token: localStorage.getItem('token') || ''
},
- 使用插件vuex-persistedstate实现持久化存储 运行如下命令,安装持久化存储 vuex 中数据的第三方包
npm install --save vuex-persistedstate@3.2.1
在 src/store/index.js 模块中,导入并配置 vuex-persistedstate 包
import Vue from 'vue'
import Vuex from 'vuex'
// 1. 导入包
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
export default new Vuex.Store({
// 2. 配置为 vuex 的插件
plugins: [createPersistedState()],
state: {
token: ''
},
mutations: {
updateToken(state, newToken) {
state.token = newToken
}
}
})
- 运用工具方法js-cookie
import Cookies from 'js-cookie'
const TokenKey = 'hrsaas-ihrm-token' // 设定一个独一无二的key
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
在mutations调用setToken(newToken)函数,传参为token
mutations: {
// 获取token值
setToken(state,newToken){
state.token = newToken
// 调用封装好的函数,做持久化 获取token
setToken(newToken)
}
},
在state取出token
state:()=>{
return {
//保存token
// 如果本地有token,就用本地的,如果没有,就为空
token: getToken() || '',
}
},
注意:在state中储存token有两种状态,一种是还未获取token时,值为空,一种是获取了token保存到了本地,用本地中的token,本地有限
在运用以上方式获取token成功之后,接下来,还需要对其进行一些优化。
首先,我们获取token的目的是为了访问后续接口
所以后续接口都需要token值
这样,我们就可以将token值直接存放在请求拦截器中
只要发起了请求,就可以自动获取token
代码如下:
// 添加请求拦截器
service.interceptors.request.use(function (config) {
// 在发送请求之前做些什么获取token值
const token = store.state.user.token
// console.log(token)
//判断:如果有token值,就将token赋值给请求头,注意,右边的值以后端需求为主
if(token){
config.headers.Authorization = `Bearer ${token}`
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
其次,获取token有两种状态,成功与失败,当获取token失败时,应当抛出这个错误,而且,当token失效时,页面应该自动跳转登录页进行重新获取:
// 响应拦截器
service.interceptors.response.use(response => {
//获取数据失败,但是响应码却是2开头,不报错,需要主动抛出错误
if (response.data.success === false) {
// 操作成功
return Promise.reject(response.data.Message)
}
// console.log(response)
//对后端返回的数据进行脱壳处理
return response.data
}, error => {
//token失效,响应码为10002,清除token与用户信息,并进行跳转
if(error.response.data.code === 10002){
store.dispatch('user/logout')
router.push('/login?return_url=' + encodeURIComponent(router.currentRoute.fullPath))
}
return Promise.reject(error) // 返回执行错误 让当前的执行链跳出成功 直接进入 catch
})
以上就是接口权限的所有内容,接口权限,主要就是获取token值,对token值的一些优处理,虽然并不复杂,但是也有很多细节。