import jwtDecode from 'jwt-decode' import axios from 'axios' const fefresh_token_api = '/OAUTH_PROXY/token/fresh_token/' class Token { constructor(requestClient) { this.moduleName = 'tokenModule' this.subscribers = [] this.isRefreshing = false this.requestClient = requestClient // 监听消息webframe 发来的消息 设置token 并且刷新队列 window.addEventListener('message', (e) => { if (self === top) return if (!e.data) return var type = e.data.type var data = e.data.data if (type === 'setToken') { console.log('设置webframe传递过来的token', data) // 设置token this.setIframeToken(data) // 通知本页面的请求重新请求 this.onAccessTokenFetched(data.token) // 解决弹出框里面的iframe过期问题 this.notifyChildUpdateToken() } }, false) } setIframeToken(data) { var token = data.token sessionStorage['token'] = token sessionStorage['refresh_token'] = data.refresh_token } // 恢复状态 cleanStatus() { this.isRefreshing = false this.subscribers = [] } // 刷新token async fefreshToken(token = sessionStorage['refresh_token']) { const result = await this.requestClient.post(fefresh_token_api, { refresh_token: token }) const { access_token, token_type, refresh_token } = result.data sessionStorage['refresh_token'] = refresh_token sessionStorage['token'] = token_type + ' ' + access_token return result } // 把当前请求推入到数组中存储起来 addSubscriber(callback) { this.subscribers.push(callback) } // token刷新成功后 把存储起来的请求执行一次 onAccessTokenFetched(token) { this.subscribers.forEach((callback) => { callback(token) }) this.cleanStatus() } // 处理401函数 hand401Meaage(config) { if (!this.isRefreshing) { this.isRefreshing = true top.postMessage({ type: 'freshToken' }, '*') } // 这个Promise函数很关键 const retryOriginalRequest = new Promise((resolve) => { this.addSubscriber(() => { resolve(axios(config)) }) }) return retryOriginalRequest } // 处理401函数 hand401MeaageWebframe(config) { if (!this.isRefreshing) { // 异步处理 token刷新成功后把缓存的请求全部刷新 this.fefreshToken().then(res => { this.onAccessTokenFetched(res) }) } // 这个Promise函数很关键 const retryOriginalRequest = new Promise((resolve) => { this.addSubscriber(() => { resolve(axios(config)) }) }) return retryOriginalRequest } // 判断token是否过期 checkTokenExpire() { const BearerToken = sessionStorage['token'] if (!BearerToken) return true const access_token = BearerToken.slice(7, BearerToken.length) const decodeTokenInfo = jwtDecode(access_token) const { exp } = decodeTokenInfo const now = Math.round(new Date() / 1000) return now - exp > 0 } // 判断过期自动刷新 async checkTokenRefreshToken() { const resultCheck = this.checkTokenExpire() if (resultCheck) { await this.fefreshToken() } } // 更新子iframe async updateChildIframeToken() { const resultCheck = this.checkTokenExpire() if (resultCheck) { await this.fefreshToken() this.notifyChildUpdateToken() } } notifyChildUpdateToken() { const refresh_token = sessionStorage['refresh_token'] const token = sessionStorage['token'] const iframes = Array.from(document.getElementsByTagName('iframe')) iframes.forEach(item => { this.postMessageBycontentWindow(item.contentWindow, { type: 'setToken', data: { refresh_token: refresh_token, token: token } }) }) } postMessageBycontentWindow(contentWindow, message) { contentWindow.postMessage(message, '*') } } export default Token