vue项目前后端分离,采用axios为异步请求的库,为了解决Rest接口访问的安全问题,需要在每次发送请求前在请求头设置一个token和签名,以在服务端根据token和签名对访问的合法性做校验。
在axios的请求拦截器做这个逻辑,具体代码如下。
/**
* http配置
*/
import axios from 'axios';
var timestamp = '';
var headtoken = '';
var sign = '';
var domain = '/bop-web';
var instance = axios.create();
function buildParamStr(param, timestamp, url, signtoken) {
param["timestamp"] = timestamp;
param["url"] = url;
param["signtoken"] = signtoken;
var keys = [];
var paramstr = "";
for (var paramkey in param) {
keys.push(paramkey);
}
keys.sort();
for (var i = 0; i < keys.length; i++) {
var itemkey = keys[i];
if (typeof(param[itemkey]) === 'object') {
param[itemkey] = JSON.stringify(param[itemkey]);
}
if (i === keys.length - 1) {
paramstr += itemkey + "=" + param[itemkey];
} else {
paramstr += itemkey + "=" + param[itemkey] + "&";
}
}
// console.log(paramstr);
return paramstr;
}
function bulidSign(paramdata, timestamp, url, signtoken) {
var paramStr = buildParamStr(paramdata, timestamp, url, signtoken);
delete paramdata.signtoken;
delete paramdata.timestamp;
delete paramdata.url;
var hash = CryptoJS.SHA256(paramStr);
// console.log(hash.toString());
return hash.toString();
}
function getToken() {
return instance({url: '/token/getToken', type: 'get'});
}
// 超时时间
axios.defaults.timeout = 5000;
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
axios.interceptors.response.use((res) => {
if(res.headers.sessionstatus === 'timeout') {
var url = btoa(window.location.href);
window.location.href = domain + "/login/logindo?r=" + url;
}
return res;
}, (error) => {
console.log(axios.interceptors.response);
return Promise.reject(error);
});
axios.interceptors.request.use(
config => {
**return getToken().then((res) => {
console.log('gettoken done');
config = config ? config : {};
config.params = config.params ? config.params : {};
timestamp = res.data.data.timestamp;
headtoken = res.data.data.headtoken;
sign = bulidSign(config.params, res.data.timestamp, config.url, res.data.signtoken);
config.headers = {
timestamp: timestamp,
headtoken: headtoken,
sign: sign
};
return config;**
}).catch((res) => {
console.log(res);
});
}, error => {
Message.error({
message: '加载超时'
});
return Promise.reject(error)
});
export default axios