axios封装了为一个http.js文件,请求响应拦截,认证生成jwt
import axios from 'axios';
import qs from 'qs';
import { Base64 } from 'js-base64';
import { HmacSHA256 } from "crypto-js";
class Http {
constructor (router) {
//设置axios默认的以post请求的头部信息
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
this.$axios = axios.create({
baseURL: '/api/',
timeout: 10000
});
//配置请求拦截器,每次请求都会经过这个方法。我们可以在这里设置一些头部信息等一切请求前需要预先处理的事情
this.$axios.interceptors.request.use(config => {
if(config.id){
config['headers']['Authorization'] = 'BEARER ' + this.getToken(config.id);
}else{
config['headers']['Authorization'] = 'BEARER ' + this.getToken();
}
config['data'] = qs.stringify(config['data']);
return config;
}, error => Promise.reject(error));
//配置响应拦截器,每次响应都会先经过这个方法。实现单用户登录在这里很简单,以及配置一些数据的处理,比如转换格式等
this.$axios.interceptors.response.use(response => {
if(response.status === 512){ //当响应状态码为512时,证明该账号在其他处登录,立即跳转到登录页
router.push({ path: "/login" });
}
if(response.status === 200) {
if(response.data) {
if(response.data.Code === 0) return Promise.resolve(response.data || true);
return Promise.reject(response.data || true);
}
return Promise.resolve(response || false);
}
return Promise.reject(response || false);
}, (error) => {
return Promise.reject(error);
});
}
/**
* 前端生成jwt。每次发送请求都会通过这个方法生成token
*
*/
getToken(id) {
let part1 = Base64.encode(
JSON.stringify({ alg: "HS256", typ: "JWT" })
);
part1.trimRight("=");
let part2;
if(id){
part2 = Base64.encode(
JSON.stringify({
timestamp:Date.parse(new Date()), //因为时间戳的不同,每次请求生成的token都不相同,提高安全性
user_id: sessionStorage.getItem('userId'),
id:id,
})
).trimRight("=");
}else{
part2 = Base64.encode(
JSON.stringify({
timestamp:Date.parse(new Date()),
user_id: sessionStorage.getItem('userId'),
id:"",
})
).trimRight("=");
}
let part3 = HmacSHA256(part1 +'.'+ part2, 'secret').toString(); //使用HmacShA256实现签名
let token = part1 + '.' + part2 + '.' + part3;
return token
};
/**
* GET
*
* @param {String} [url] - 链接
* @param {Object} [params] - 参数
* @param {Boolean} [msg] - 是否错误弹出框
*/
get (url, params = {}, msg = true) {
return new Promise((resolve, reject) => {
this.$axios.get(`${url}`, {
params
}).then(response => {
if(response.code === 1) return resolve(response.data || true);
msg && this.$msg.error('获取数据失败');
reject(response || false);
}).catch(err => {
msg && this.$msg.error('获取数据失败');
reject(err || false);
});
});
}
/**
* POST
*
* @param {String} [url] - 链接
* @param {Object} [data] - 数据
* @param {Object} [config] - 配置
*/
post (url, data = {}, config = {}) {
return this.$axios.post(`${url}`, data, config);
}
/**
* PUT
*
* @param {String} [url] - 链接
* @param {Object} [data] - 数据
* @param {Object} [config] - 配置
*/
}
export default Http //export构造函数
在main.js实例化对象并赋值给vue的原型对象的$http,这里将VueRouter作为参数是因为在响应拦截器中需要进行页面跳转