更新日期:2019年2月13日
axios-auth-refresh package
这将帮助您实现此处指定的行为。
这里的关键是返回正确的Promise对象,这样您就可以使用
.then()
用于链锁。我们可以使用Vuex的状态来实现这一点。如果发生刷新调用,我们不仅可以设置
refreshing
陈述
true
,我们还可以将刷新调用设置为挂起的调用。这样使用
function refreshToken(store) {
if (store.state.auth.isRefreshing) {
return store.state.auth.refreshingCall;
}
store.commit('auth/setRefreshingState', true);
const refreshingCall = Axios.get('get token').then(({ data: { token } }) => {
store.commit('auth/setToken', token)
store.commit('auth/setRefreshingState', false);
store.commit('auth/setRefreshingCall', undefined);
return Promise.resolve(true);
});
store.commit('auth/setRefreshingCall', refreshingCall);
return refreshingCall;
}
这将始终返回已创建的请求作为承诺,或者创建新请求并将其保存以供其他调用。现在,您的拦截器将类似于下面的拦截器。
Axios.interceptors.response.use(response => response, error => {
const status = error.response ? error.response.status : null
if (status === 401) {
return refreshToken(store).then(_ => {
error.config.headers['Authorization'] = 'Bearer ' + store.state.auth.token;
error.config.baseURL = undefined;
return Axios.request(error.config);
});
}
return Promise.reject(error);
});
这将允许您再次执行所有挂起的请求。但这一切都是同时发生的,没有任何疑问。
refreshToken()
功能,就像这样。
function refreshToken(store, cb) {
if (store.state.auth.isRefreshing) {
const chained = store.state.auth.refreshingCall.then(cb);
store.commit('auth/setRefreshingCall', chained);
return chained;
}
store.commit('auth/setRefreshingState', true);
const refreshingCall = Axios.get('get token').then(({ data: { token } }) => {
store.commit('auth/setToken', token)
store.commit('auth/setRefreshingState', false);
store.commit('auth/setRefreshingCall', undefined);
return Promise.resolve(token);
}).then(cb);
store.commit('auth/setRefreshingCall', refreshingCall);
return refreshingCall;
}
Axios.interceptors.response.use(response => response, error => {
const status = error.response ? error.response.status : null
if (status === 401) {
return refreshToken(store, _ => {
error.config.headers['Authorization'] = 'Bearer ' + store.state.auth.token;
error.config.baseURL = undefined;
return Axios.request(error.config);
});
}
return Promise.reject(error);
});
我还没有测试第二个示例,但它应该可以工作,或者至少给您一个想法。
Working demo of first example
-由于模拟请求和用于它们的服务的演示版本,它在一段时间后将无法工作,但代码仍然存在。
资料来源:
Interceptors - how to prevent intercepted messages to resolve as an error