내 앱에서는 API 미들웨어를 통해 모든 요청을 실행하고 있습니다. 인증 요청 이 발생하고 만료 된 토큰이 있을 때 미들웨어 재시도 기능을 만들려고합니다 . 내 현재 API 미들웨어는 다음과 같습니다.
const apiMiddleware = ({ dispatch }) => next => action => {
next(action);
// creating request data and params
const retryRequest = () => {
// refresh tokens with method: dispatch(getTokens());
// retry initial request
};
axios({
method,
url,
headers,
[dataOrParams]: data,
})
.then(({ data: apiData }) => {
dispatch(onSuccess(apiData));
})
.catch(error => {
if (withToken && error.response.status === 401) {
retryRequest();
}
return dispatch(apiError(label, error));
})
};
export default apiMiddleware;
retryRequest()
메서드를 호출 하면 getTokens()
요청이 시작되지만 동시에 초기 요청이 시작되고 Redux는 아직 새 새로 고침 토큰으로 업데이트 getTokens()
되지 않았으며 완료되지 않았기 때문에 요청이 다시 실패합니다 .
내가 잘못하고 있다는 것을 이해합니다. 다른 어떤 해결책을 시도 할 수 있습니까? 따라서 첫 번째 요청 getTokens()
이 호출되고 완료되면 초기 요청이 계속 될 수 있습니다.
retryRequest () 및 catch 함수를 비동기로 만들 수 있으면 다음을 사용할 수 있습니다.
if(withToken && error.reponse.status === 401)
await retryRequest();
return dispatch(apiError(label, error));
할 수 없다면 재시도 요청에서 약속을 반환하고
if(withToken && error.response.status === 401)
return retryRequest().then(_=> dispatch(apiError(label, error)))
return dispatch(apiError(label, error))
axios 인터셉터를 사용할 수도 있습니다. 이것은 제가 가장 최근 프로젝트에서 사용한 것입니다.
api.interceptors.response.use(
function (response) {
response.data = parseResponseData(response.data);
return response;
},
async function (error) {
if (!error.response)
Ant.message.error('Não foi possivel se conectar com o servidor');
else if (
error.response.status === 500 &&
window.location.pathname !== '/erro/500'
) {
if ((error.config.method as string).toLowerCase() === 'get')
navigate('/erro/500');
else
Ant.message.error(
'Desculpe, parece que algo deu errado no servidor.',
);
} else if (error.response.status === 401) {
let request = error.config;
const auth = localStorage.getItem('auth');
let refreshToken = auth && JSON.parse(auth)['refreshToken'];
var authService = new AuthService();
return await authService
.refresh(refreshToken)
.then(async (resp) => {
store.dispatch(login(resp.data));
let axiosInstance = axios.create();
intercept(axiosInstance);
return await axiosInstance.request(request);
})
.catch((e) => {
if (
window.location.pathname !== '/login' &&
(!e.response || e.response.status === 401)
)
navigate('/login');
});
}
return error.response;
},
);
지금까지 꽤 잘 작동했습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다