xiaosi
1 year ago
4 changed files with 345 additions and 0 deletions
@ -0,0 +1,62 @@ |
|||
/** |
|||
* 认证助手 |
|||
*/ |
|||
import jwtDecode from 'jwt-decode'; |
|||
|
|||
class Auth { |
|||
token = null; |
|||
|
|||
saveToken(accessToken) { |
|||
this.token = accessToken; |
|||
localStorage.setItem('token', accessToken); |
|||
// sessionStorage.setItem('token', accessToken);
|
|||
} |
|||
|
|||
getToken() { |
|||
if (!this.token) { |
|||
this.token = localStorage.getItem('token'); |
|||
// this.token = sessionStorage.getItem('token');
|
|||
} |
|||
|
|||
return this.token; |
|||
} |
|||
|
|||
removeToken() { |
|||
this.token = null; |
|||
// localStorage.removeItem('token');
|
|||
sessionStorage.removeItem('token'); |
|||
} |
|||
|
|||
getPayload() { |
|||
if (!this.getToken()) { |
|||
return {}; |
|||
} |
|||
|
|||
let payload = null; |
|||
try { |
|||
payload = jwtDecode(this.token); |
|||
} catch (e) { |
|||
//
|
|||
} |
|||
|
|||
return payload || {}; |
|||
} |
|||
|
|||
checkToken() { |
|||
const { exp } = this.getPayload(); |
|||
|
|||
if (!exp) { |
|||
this.removeToken(); |
|||
return false; |
|||
} |
|||
|
|||
const valid = Date.now() < exp * 1000; |
|||
if (!valid) { |
|||
this.removeToken(); |
|||
} |
|||
|
|||
return valid; |
|||
} |
|||
} |
|||
|
|||
export default new Auth(); |
@ -0,0 +1,115 @@ |
|||
/** |
|||
* 请求 |
|||
*/ |
|||
import axios from 'axios'; |
|||
import auth from './auth'; |
|||
|
|||
// vue-cli / webpack 使用 process.env.NODE_ENV
|
|||
// vite 使用 import.meta.env.MODE
|
|||
const { [import.meta.env.MODE]: REQUEST_TIMEOUT } = { |
|||
development: 600000, |
|||
production: 6000, |
|||
}; |
|||
|
|||
class Http { |
|||
instanceWithToken = axios.create({ |
|||
timeout: REQUEST_TIMEOUT, |
|||
headers: { |
|||
Accept: 'application/json', |
|||
'Content-Type': 'application/json', |
|||
'Accept-Language': 'zh-CN', |
|||
'Terminal-Type': 'web', |
|||
}, |
|||
withCredentials: true, |
|||
}); |
|||
|
|||
instanceWithoutToken = axios.create({ |
|||
timeout: REQUEST_TIMEOUT, |
|||
headers: { |
|||
Accept: 'application/json', |
|||
'Content-Type': 'application/json', |
|||
'Accept-Language': 'zh-CN', |
|||
'Terminal-Type': 'web', |
|||
}, |
|||
withCredentials: true, |
|||
}); |
|||
|
|||
// 认证失败处理
|
|||
// eslint-disable-next-line class-methods-use-this
|
|||
authFailureHandler() { |
|||
} |
|||
|
|||
// 请求拦截
|
|||
requestInterceptor = (config) => { |
|||
if (!auth.checkToken()) { |
|||
this.authFailureHandler(); |
|||
return Promise.reject(new Error('请重新登录')); |
|||
} |
|||
const conf = config; |
|||
const token = auth.getToken(); |
|||
conf.headers.Authorization = `Bearer ${token}`; |
|||
return conf; |
|||
}; |
|||
|
|||
// 响应拦截
|
|||
// eslint-disable-next-line class-methods-use-this
|
|||
responseInterceptor = (response) => response; |
|||
|
|||
// 出错处理
|
|||
errorHandler = (error) => { |
|||
const { response, request } = error; |
|||
const { status } = response || request || {}; |
|||
if (status === 401) { |
|||
this.authFailureHandler(); |
|||
} |
|||
if (response) { |
|||
if (typeof response.data !== 'object') { |
|||
return Promise.reject(error.toJSON()); |
|||
} |
|||
return Promise.reject(response.data); |
|||
} |
|||
if (request) { |
|||
if (request.status === 0) { |
|||
return Promise.reject(error.toJSON()); |
|||
} |
|||
return Promise.reject(request); |
|||
} |
|||
return Promise.reject(error); |
|||
}; |
|||
|
|||
constructor() { |
|||
this.instanceWithToken.interceptors.request.use(this.requestInterceptor, this.errorHandler); |
|||
this.instanceWithToken.interceptors.response.use(this.responseInterceptor, this.errorHandler); |
|||
this.instanceWithoutToken.interceptors.response.use(this.responseInterceptor, this.errorHandler); |
|||
} |
|||
|
|||
/** |
|||
* 获取axios实例 |
|||
* @param withToken 请求时是否携带token |
|||
* @returns {AxiosInstance} |
|||
*/ |
|||
getInstance(withToken = true) { |
|||
return withToken ? this.instanceWithToken : this.instanceWithoutToken; |
|||
} |
|||
|
|||
uploadBlob(url, blob) { |
|||
const formData = new FormData(); |
|||
formData.append('file', blob); |
|||
return this.getInstance().post(url, formData, { headers: { 'Content-Type': 'multipart/form-data' } }); |
|||
} |
|||
|
|||
downloadBlob(url, queries = {}) { |
|||
return this.getInstance(false).get(url, { |
|||
responseType: 'blob', |
|||
params: queries, |
|||
}); |
|||
} |
|||
|
|||
// 注册->认证失败处理函数
|
|||
registerAuthFailureHandler(handler) { |
|||
if (typeof handler !== 'function') return; |
|||
this.authFailureHandler = handler; |
|||
} |
|||
} |
|||
|
|||
export default new Http(); |
Loading…
Reference in new issue