From 69b0023765f361542b2930bf78cf133f7d73f161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=98=88=EC=A7=84?= Date: Sat, 17 Aug 2024 20:22:10 +0900 Subject: [PATCH] feat: add axios interceptor for authorization --- src/shared/lib/custom_instance.ts | 64 ++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/shared/lib/custom_instance.ts b/src/shared/lib/custom_instance.ts index 8ba7b2d..8e17863 100644 --- a/src/shared/lib/custom_instance.ts +++ b/src/shared/lib/custom_instance.ts @@ -1,10 +1,70 @@ import axios, { AxiosRequestConfig } from 'axios'; +import { refreshToken } from 'src/types'; + +const instance = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL }); + +const getAccessToken = () => localStorage?.getItem('accessToken') ?? null; + +instance.interceptors.request.use( + (config) => { + if (!config.headers) return config; + + let token = null; + + if (!config.url?.includes(`/api/v1/auth/refresh-token`)) { + token = getAccessToken(); + } + + if (token !== null) { + config.headers.Authorization = `Bearer ${token}`; + } + + return config; + }, + (error) => { + return Promise.reject(error); + }, +); + +const getRefreshToken = async () => { + try { + const token = getAccessToken(); + if (!token) return null; + + const response = await refreshToken({ accessToken: token }); + + return response.accessToken; + } catch (e) { + return null; + } +}; + +instance.interceptors.response.use( + (response) => { + return response; + }, + async (error) => { + const { config } = error; + + if (config.url.includes('refresh-token') || error.response.status !== 401 || config.sent) { + return Promise.reject(error); + } + + config.sent = true; + const accessToken = await getRefreshToken(); + + if (accessToken) { + config.headers.Authorization = accessToken; + } + + return axios(config); + }, +); export const customInstance = (config: AxiosRequestConfig, options?: AxiosRequestConfig): Promise => { - const promise = axios({ + const promise = instance({ ...config, ...options, - baseURL: import.meta.env.VITE_API_BASE_URL, }).then(({ data }) => data); return promise;