diff --git a/src/components/common/TableBody/index.tsx b/src/components/common/TableBody/index.tsx index 566a588f..6e1938d8 100644 --- a/src/components/common/TableBody/index.tsx +++ b/src/components/common/TableBody/index.tsx @@ -42,10 +42,12 @@ const TableBody = ({ key={rowIndex} className={cn('h-16 cursor-pointer odd:bg-grey-50 hover:bg-grey-100')} onClick={ - onRowClick && type === 'list' && typeof item.설문ID === 'number' - ? () => onRowClick(item.설문ID as number) - : onRowClick && type === 'list' && typeof item.식단ID === 'string' - ? () => onRowClick(item.식단ID as string) + onRowClick && type === 'list' && typeof item['설문 ID'] === 'number' + ? () => onRowClick(item['설문 ID'] as number) + : onRowClick && + type === 'list' && + typeof item['식단 ID'] === 'string' + ? () => onRowClick(item['식단 ID'] as string) : undefined } > diff --git a/src/lib/axios.ts b/src/lib/axios.ts index ce69539e..f086e733 100644 --- a/src/lib/axios.ts +++ b/src/lib/axios.ts @@ -1,6 +1,12 @@ import { env } from '@/lib/env'; -import axios, { AxiosResponse } from 'axios'; +import axios, { + AxiosError, + AxiosRequestConfig, + AxiosResponse, + InternalAxiosRequestConfig, +} from 'axios'; import { parseCookies } from 'nookies'; +import { destroyTokens } from '@/utils/destroyTokens'; import { saveTokens } from '@/utils/saveTokens'; import { AUTH_API } from '@/constants/_apiPath'; import { AUTH_LINKS } from '@/constants/_auth'; @@ -33,11 +39,13 @@ const instance = axios.create({ }); instance.interceptors.request.use( - (config) => { - const accessToken = getAccessToken(); - - if (accessToken) { - config.headers.Authorization = `Bearer ${accessToken}`; + (config: InternalAxiosRequestConfig) => { + if (typeof window !== 'undefined') { + const accessToken = getAccessToken(); + if (accessToken) { + config.headers = config.headers || {}; + config.headers.Authorization = `Bearer ${accessToken}`; + } } return config; }, @@ -46,28 +54,54 @@ instance.interceptors.request.use( }, ); +type RefreshQueueItem = { + config: AxiosRequestConfig; + resolve: (value: AxiosResponse) => void; + reject: (reason?: AxiosError) => void; +}; + +let isRefreshed = false; +let refreshAndRetryQueue: RefreshQueueItem[] = []; + instance.interceptors.response.use( (response) => { return response; }, async (error) => { - const originalRequest = error.config; + const originalRequest = error.config as AxiosRequestConfig & { + headers: Record; + }; + + if (error.response?.status === 400) { + return Promise.resolve(); + } if ( !originalRequest || error.response?.status !== 410 || - originalRequest.headers._retry !== '0' + originalRequest.headers._retry === '1' ) { return Promise.reject(error); } + originalRequest.headers._retry = '1'; + const refreshToken = parseCookies().refreshToken; if (!refreshToken) { redirectToLogin(); + destroyTokens(); return Promise.reject(error); } + if (isRefreshed) { + return new Promise((resolve, reject) => { + refreshAndRetryQueue.push({ config: originalRequest, resolve, reject }); + }); + } + + isRefreshed = true; + try { const response = await axios.get( `${env.BASE_API_URL}${AUTH_API.REISSUE}`, @@ -82,13 +116,27 @@ instance.interceptors.response.use( saveTokens({ accessToken, refreshToken: newRefreshToken }); originalRequest.headers.Authorization = `Bearer ${accessToken}`; - originalRequest.headers._retry = '1'; - return await instance(originalRequest); - } else { - throw new Error('Failed to reissue tokens'); + + refreshAndRetryQueue.forEach(({ config, resolve, reject }) => { + config.headers = { + ...config.headers, + Authorization: `Bearer ${accessToken}`, + }; + instance.request(config).then(resolve).catch(reject); + }); + + refreshAndRetryQueue = []; + + return instance(originalRequest); } } catch (refreshError) { + destroyTokens(); + redirectToLogin(); + refreshAndRetryQueue.forEach(({ reject }) => reject(error as AxiosError)); + refreshAndRetryQueue = []; return Promise.reject(refreshError); + } finally { + isRefreshed = false; } }, ); diff --git a/src/test.md b/src/test.md deleted file mode 100644 index 9daeafb9..00000000 --- a/src/test.md +++ /dev/null @@ -1 +0,0 @@ -test