需求:
由其他平台直接跳转进入当前平台A,只携带了用户名信息,平台A展示数据需要验证用户身份,因此,需要先用用户名称获取token再请求其他接口,展示页面数据。
根据不同用户展示不同数据。
分析:
1.进入页面前先使用用户名–>换取token,
2.请求页面数据时,将token携带在请求头中,
方案:
1.在request拦截器中做异步请求,获取到token再释放拦截器
弊端:拦截接口导致当前页面请求的接口会多次重复请求,此方法业务逻辑不流畅,不采用
2.在当前页面的周期函数created中请求token,在仓库中异步获取token后,将token存储在本地sessionStorage中,并全局挂在在state中,在异步函数的回调中请求页面的数据接口。
优点:完成异步请求,并全局挂载了token数据,避免多次重复请求接口。
实现:
- index页面,异步请求toekn,回调成功后加载当前页面及子页面数据
html
<template>
<div class="mainPage">
<Banner></Banner>
<SceneRecommend ref="sceneCommend" ></SceneRecommend>
<Prefecture ref="prefectueRef"></Prefecture>
<newExploreVue ref="newExpRef"></newExploreVue>
<Help class="help-ele" ref="helpPage"></Help>
</div>
</template>
js
data(){
return {
reqIndex: 0, // token失败请求次数
}
},
created() {
this.getQToken();
},
methods: {
getQToken() {
// HACK: 使用vuex执行异步请求token操作
let TokenASession = JSON.parse(sessionStorage.getItem('Cusertoken'));
if (TokenASession) {
console.log("已获取token", TokenASession);
this.$nextTick(() => {
// 父组件调用子组件的方法,子组件函数请求接口数据
setTimeout(() => {
this.$refs.sceneCommend.init();
this.$refs.prefectueRef.getSpectacle();
this.$refs.newExpRef.getUserAdmin();
}, 1000);
})
return
}
// 这里设置一个参数,用于token请求未通过时,尝试3次调用token接口
let index = localStorage.getItem("reqIndex")
if (index) { // 已经请求token超过3次,未获取token,不再请求接口
return
}
// 异步请求token
this.$store.dispatch('integrate/getByUserToken')
.then((res) => {
console.log('成功存储!!!!!', res);
if (res == 'success-token') {
// 正常获取
setTimeout(() => {
this.$refs.sceneCommend.init();
this.$refs.prefectueRef.getSpectacle();
this.$refs.newExpRef.getUserAdmin();
}, 500);
} else {
this.reqIndex++
if (this.reqIndex < 3) { // 再次尝试调用
this.getQToken();
console.log("验证次数", this.reqIndex);
} else {
localStorage.setItem("reqIndex", this.reqIndex)
location.reload();
}
}
})
},
},
beforeDestroy(){
// 离开页面前清除此数据
localStorage.removeItem("reqIndex")
},
vuex页面异步请求token并存储
const state = {
formToken: JSON.parse(sessionStorage.getItem('formToken')) || null,
}
const mutations = {
SET_FORM_TOKEN: (state, formToken) => {
state.formToken = formToken;
let space = JSON.stringify(formToken);
sessionStorage.setItem("formToken",space)
},
}
const actions = {
getByUserToken({ commit }, username) {
return new Promise((resolve, reject) => {
let namecode = JSON.parse(sessionStorage.getItem("userInfo")).nameCode;
let data = { username: namecode }
getplatUserToken(data)
.then(res => {
console.log('vuex测试 =>获取用户token===》', res.data);
let token = res.data.token
if (token) {
commit('SET_FORM_TOKEN', token);
resolve("success-token")
}else{
resolve("fail-token");
console.log("获取token失误",res);
}
}).catch((err)=>{
resolve("fail-token");
})
})
},
}
3.注意:
然后当前我的接口API是通过转发的方式请求的,因为不是本地后端接口,接入的其他平台接口,所以做统一转发处理,所以直接将token 放在接口API中了
这里大家可以根据自己的请求方式,统一设置就好
接口API文件
import { request1 } from "./request";
// 平台用户token获取
export function getplatUserToken(params) {
return request1({
url: '/common/forward',
method: 'post',
data:{
url: 'http://**.**.*.***:****/qybb/api/getTokenByUser',
method: 'POST',
body: params,
headers: {
projectId: '************'
}
}
})
}
写到这里就完结啦,这就是当前平台的处理方式了,如果不使用转发接口的话,其实可以在获取token后,在拦截器中取出token放在请求头中,然后,这时候子组件的接口刚好调用,就可以完成异步请求数据的需求啦。