Axios:在 POST 之前组合来自拦截器和来自组件的数据请求
Axios: combining data request from interceptors and from component before POST
我有这个功能动作
export function unlinkAccount(id) {
return function(dispatch) {
const data = {
id: id
};
return userApi
.post('/user/account/unlink', data)
.then(res => console.log('SUCCESS: unlinkAccount -> ', res))
.catch(err => console.log('ERROR: unlinkAccount -> ', err));
};
}
但我也按照以下方式拦截了请求
userApi.interceptors.request.use(
async config => {
const jwtToken = await refreshToken();
if (jwtToken) {
config.data = { accessToken: jwtToken };
}
return config;
},
error => {
return Promise.reject(error);
}
);
这将使用来自拦截器的数据而不是 unlinkAccount
函数从 POST 到 userApi
。有没有办法合并这两个数据或作为 'props' 传递给 unlinkAccount
函数,因为我需要按照以下格式传递数据:
const data = {
id: id,
accessToken: jwtToken
}
谢谢。
这是我过去所做的:
我认为每次调用 api 时都传递 jwtToken 不是一个好方法。
如果你使用下面的,你只需要
const data = {
id: id
};
return userApi
.post('/user/account/unlink', data)
此外,您不需要每次都调用 refreshToken。
import axios from 'axios';
import { store } from '../index';
import { updateAuth } from '../redux/actions/auth';
import { apiURL } from '../config';
axios.defaults.baseURL = apiURL;
// Add a request interceptor
axios.interceptors.request.use(
(config) => {
const { tokenType, accessToken, loggedIn } = store.getState().auth;
const token = `${tokenType} ${accessToken}`;
if (loggedIn) {
config.headers['Authorization'] = token;
}
config.headers['Content-Type'] = 'application/json';
return config;
},
(error) => {
Promise.reject(error);
}
);
//Add a response interceptor
axios.interceptors.response.use(
(response) => {
return response;
},
function(error) {
const originalRequest = error.config;
if (
error.response.status === 401 &&
(originalRequest.url === `${apiURL}auth/login` ||
originalRequest.url === `${apiURL}auth/refresh-token`)
) {
// router.history.push('/auth/login');
return Promise.reject(error);
}
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
const { refreshToken } = store.getState().auth;
const { email } = store.getState().user;
return axios
.post('/auth/refresh-token', {
email,
refreshToken
})
.then((response) => {
const { data: res } = response;
if (res.code === 200) {
store.dispatch(updateAuth({ ...res.token }));
const { tokenType, accessToken } = res.token;
axios.defaults.headers.common[
'Authorization'
] = `${tokenType} ${accessToken}`;
return axios(originalRequest);
}
});
}
return Promise.reject(error);
}
);
export default axios;
是的,只是找出解决方案,我只是将拦截器请求中的 config.data 更改为
if (jwtToken) {
config.data = { accessToken: jwtToken, ...config.data };
}
所以它会从组件中获取数据并在制作 POST 之前合并拦截数据。
我有这个功能动作
export function unlinkAccount(id) {
return function(dispatch) {
const data = {
id: id
};
return userApi
.post('/user/account/unlink', data)
.then(res => console.log('SUCCESS: unlinkAccount -> ', res))
.catch(err => console.log('ERROR: unlinkAccount -> ', err));
};
}
但我也按照以下方式拦截了请求
userApi.interceptors.request.use(
async config => {
const jwtToken = await refreshToken();
if (jwtToken) {
config.data = { accessToken: jwtToken };
}
return config;
},
error => {
return Promise.reject(error);
}
);
这将使用来自拦截器的数据而不是 unlinkAccount
函数从 POST 到 userApi
。有没有办法合并这两个数据或作为 'props' 传递给 unlinkAccount
函数,因为我需要按照以下格式传递数据:
const data = {
id: id,
accessToken: jwtToken
}
谢谢。
这是我过去所做的:
我认为每次调用 api 时都传递 jwtToken 不是一个好方法。 如果你使用下面的,你只需要
const data = {
id: id
};
return userApi
.post('/user/account/unlink', data)
此外,您不需要每次都调用 refreshToken。
import axios from 'axios';
import { store } from '../index';
import { updateAuth } from '../redux/actions/auth';
import { apiURL } from '../config';
axios.defaults.baseURL = apiURL;
// Add a request interceptor
axios.interceptors.request.use(
(config) => {
const { tokenType, accessToken, loggedIn } = store.getState().auth;
const token = `${tokenType} ${accessToken}`;
if (loggedIn) {
config.headers['Authorization'] = token;
}
config.headers['Content-Type'] = 'application/json';
return config;
},
(error) => {
Promise.reject(error);
}
);
//Add a response interceptor
axios.interceptors.response.use(
(response) => {
return response;
},
function(error) {
const originalRequest = error.config;
if (
error.response.status === 401 &&
(originalRequest.url === `${apiURL}auth/login` ||
originalRequest.url === `${apiURL}auth/refresh-token`)
) {
// router.history.push('/auth/login');
return Promise.reject(error);
}
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
const { refreshToken } = store.getState().auth;
const { email } = store.getState().user;
return axios
.post('/auth/refresh-token', {
email,
refreshToken
})
.then((response) => {
const { data: res } = response;
if (res.code === 200) {
store.dispatch(updateAuth({ ...res.token }));
const { tokenType, accessToken } = res.token;
axios.defaults.headers.common[
'Authorization'
] = `${tokenType} ${accessToken}`;
return axios(originalRequest);
}
});
}
return Promise.reject(error);
}
);
export default axios;
是的,只是找出解决方案,我只是将拦截器请求中的 config.data 更改为
if (jwtToken) {
config.data = { accessToken: jwtToken, ...config.data };
}
所以它会从组件中获取数据并在制作 POST 之前合并拦截数据。