fix: refresh token

This commit is contained in:
alt0
2022-12-20 19:11:40 +08:00
parent 12761f19a0
commit 97487b8259
4 changed files with 50 additions and 19 deletions
+6 -2
View File
@@ -1,6 +1,6 @@
import axios from 'axios';
import { setAuthorization } from './request';
import { handleResponseError } from './response';
import { handleResponseError, handleResponse } from './response';
declare module 'axios' {
interface AxiosRequestConfig {
@@ -8,6 +8,10 @@ declare module 'axios' {
* If true, request will send with Authorization header.
*/
withAuthorization?: boolean;
/**
* If true, indicate this request is refreshing token.
*/
refreshTokenRequest?: boolean;
}
}
@@ -16,4 +20,4 @@ export const request = axios.create({
});
request.interceptors.request.use(setAuthorization);
request.interceptors.response.use(handleResponseError);
request.interceptors.response.use(handleResponse, handleResponseError);
@@ -76,19 +76,7 @@ export async function setAuthorization(config: AxiosRequestConfig<unknown>) {
throw new Error('No authorization token.');
}
if (isAccessTokenExpired(token.accessToken)) {
if (!refreshingToken) {
refreshingToken = login({
type: 'Refresh',
token: token.refreshToken,
});
}
const newToken = await refreshingToken;
token = {
accessToken: newToken.token,
refreshToken: newToken.refresh,
};
setToken(token);
refreshingToken = undefined;
await refreshToken();
}
if (!config.headers) {
config.headers = {};
@@ -97,3 +85,23 @@ export async function setAuthorization(config: AxiosRequestConfig<unknown>) {
}
return config;
}
export const refreshToken = async () => {
let token = getToken();
if (!token) {
throw new Error('No authorization token.');
}
if (!refreshingToken) {
refreshingToken = login({
type: 'Refresh',
token: token.refreshToken,
});
}
const newToken = await refreshingToken;
token = {
accessToken: newToken.token,
refreshToken: newToken.refresh,
};
setToken(token);
refreshingToken = undefined;
};
@@ -1,8 +1,27 @@
import type { AxiosResponse } from 'axios';
import type { AxiosResponse, AxiosError } from 'axios';
import { ServiceError } from '../ServiceError';
import { refreshToken } from '../request/authorization';
import { request } from '../axios';
export function handleResponseError(response: AxiosResponse<any, any>) {
const { data, status } = response;
export async function handleResponseError(error: AxiosError<any, any>) {
const { response, config, message } = error;
const status = response?.status;
if (status === 401) {
if (!config) {
throw new ServiceError(message, status.toString());
}
if (config.refreshTokenRequest) {
throw new ServiceError(message, status.toString());
}
await refreshToken();
return request({ ...config, refreshTokenRequest: true });
}
return response;
}
export async function handleResponse(response: AxiosResponse<any, any>) {
const { status, data } = response;
if (status === 200) {
if (data.error) {
// TODO - common error handling
@@ -1 +1 @@
export { handleResponseError } from './handle-error';
export { handleResponseError, handleResponse } from './handle-error';