vuejs2 - 刷新令牌后,将原始请求的响应存储在 vuex 存储中
问题描述
我有一个 vuex 模块,其中包含通过 axios 支持的服务向 API 发出请求的操作。请求成功后,我使用模块的突变将响应存储在本地。
我使用 JWT 令牌对调用进行身份验证。我的身份验证令牌可能会过期,当它过期时,我会调用 API 以刷新令牌。
我使用拦截器来检测响应是否为 401,存储原始请求,调用刷新令牌并进行包含刷新令牌的原始调用。
目前,我有两个问题:
- 因为模块中不再发生调用,所以我无法存储响应。
- 模块中的第一个请求失败,因此我将错误消息发送到突变。
我有办法维护原始链并使第二个请求响应返回到模块吗?
axios.js
import axios from 'axios';
import { authService } from '@/services'
import store from '@/store'
import i18n from '@/i18n.js';
function isExpiredTokenError(data) {
return (data.errors && data.errors.find((error) => error.code == 'expired_token'))
}
function storeToken({ access_token, refresh_token }) {
/* do some stuff to store the token in localStorage and the a vuex store */
axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
}
function refreshExpiredToken(originalConfig) {
originalConfig._retry = true;
const storedRefreshToken = store.state.auth.refreshToken
authService.refreshToken(storedRefreshToken)
.catch(function (error) {
if (error.response) {
delete axios.defaults.headers.common['Authorization']
store.dispatch('auth/logout', { error: i18n.t('errors.need_to_relog') })
}
return Promise.reject(error);
})
.then(response => {
const oauthToken = response['data']
storeToken(oauthToken)
return axios(originalConfig);
})
}
const requestInterceptor = axios.interceptors.request.use(function (config) {
const accessToken = store.state.auth.accessToken;
if (accessToken)
config.headers.Authorization = `Bearer ${accessToken}`;
return config;
}, function (err) {
return Promise.reject(err);
});
const responseInterceptor = axios.interceptors.response.use(response => {
const type = response.headers['content-type']
if (type.includes('json'))
return response.data
else
return response
}, error => {
const originalConfig = error.config;
if (error.response.status === 401) {
if (isExpiredTokenError(error.response.data) && !originalConfig._retry) {
refreshExpiredToken(originalConfig)
} else {
store.dispatch('auth/logout', { error: i18n.t('errors.something_went_wrong') })
return Promise.reject(error);
}
}
});
export default function setup() {
requestInterceptor
responseInterceptor
}
users.service.js
import { axiosFetcher } from '@/helpers';
export const usersService = {
retrieveUsers,
}
function retrieveUsers(amount) {
const requestOptions = {
method: 'POST',
data: {
amount
},
};
return axiosFetcher(`/users`, requestOptions)
.then((response) => {
return response['data']
}, (error) => {
return error
})
}
vuex 模块 users.js
import { usersService } from '@/services'
const getDefaultState = () => {
return { users: [], error: null }
}
const state = getDefaultState()
const actions = {
retrieveUsers({ commit }) {
usersService.retrieveUsers()
.then(
(response) => {
if (response.isAxiosError) {
commit('requestUsersFailure', response.message)
} else {
commit('requestUsersSuccess', response)
}
}
)
},
}
const mutations = {
requestUsersFailure(state, error) {
state.error = error
},
requestUsersSuccess(state, users) {
state.users = users
},
}
const getters = {}
export const users = {
namespaced: true,
state,
actions,
mutations,
getters,
}
我打电话this.$store.commit('users/retrieveUsers')
解决方案
推荐阅读
- xamarin.android - Resource.id 不包含定义或未找到。它会自行修复然后再次中断
- postgresql - 如何给内置的 PostgreSQL 函数起别名?
- spring - spring oauth2在单页应用程序中授权流程
- algorithm - 迭代 O(2^n) 算法的示例
- apache-spark - SnowFlake AWS Glue 集成问题
- vim - Vim ALE 处理我正在编辑的文件的旧版本
- typeorm - 更新单表继承中的实体类型
- python - 如何在 Azure Databricks PySpark 中执行存储过程?
- javascript - 使用 node.js 获取用户名并重定向(成功/失败)
- web-scraping - 构建网络爬虫时轮换 IP 地址的好方法是什么?