diff --git a/src/apis/instance.ts b/src/apis/instance.ts index 8f61c2f4..c23e83dd 100644 --- a/src/apis/instance.ts +++ b/src/apis/instance.ts @@ -1,4 +1,4 @@ -import axios from 'axios'; +import axios, { isAxiosError } from 'axios'; import { LoginResponse } from '@/apis/login/loginInterface'; import MESSAGES from '@/apis/messages'; @@ -24,17 +24,22 @@ export const privateInstance = axios.create({ // refresh token api export async function postRefreshToken() { - const response = await axios.post( - `${API_URL}/api/auth/re-issue`, - {}, - { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${localStorage.getItem('refreshToken')}`, - }, - } - ); - return response; + try { + const response = await axios.post( + `${API_URL}/api/auth/re-issue`, + {}, + { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${localStorage.getItem('refreshToken')}`, + }, + } + ); + return response; + } catch (error) { + if (isAxiosError(error)) throw error; + else throw new Error(MESSAGES.UNKNOWN_ERROR); + } } privateInstance.interceptors.response.use( @@ -49,23 +54,24 @@ privateInstance.interceptors.response.use( // 토큰이 만료되을 때 if (status === 401) { const originRequest = config; - const response = await postRefreshToken(); - - // 리프레시 토큰 요청이 성공할 때 - if (response.status === 200) { - const newAccessToken = response.data.data.accessToken; - localStorage.setItem('accessToken', newAccessToken); - localStorage.setItem('refreshToken', response.data.data.refreshToken); - axios.defaults.headers.common.Authorization = `Bearer ${newAccessToken}`; - // 진행중이던 요청 이어서하기 - originRequest.headers.Authorization = `Bearer ${newAccessToken}`; - return axios(originRequest); - } - if (response.status === 401) { + try { + const response = await postRefreshToken(); + // 리프레시 토큰 요청이 성공할 때 + if (response.status === 200) { + const newAccessToken = response.data.data.accessToken; + localStorage.setItem('accessToken', newAccessToken); + localStorage.setItem('refreshToken', response.data.data.refreshToken); + axios.defaults.headers.common.Authorization = `Bearer ${newAccessToken}`; + // 진행중이던 요청 이어서하기 + originRequest.headers.Authorization = `Bearer ${newAccessToken}`; + return await axios(originRequest); + } + } catch (err) { + // 리프레시 토큰 요청이 실패할 때 + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); alert(MESSAGES.LOGIN.EXPIRED); window.location.replace('/'); - } else { - alert(MESSAGES.UNKNOWN_ERROR); } } return Promise.reject(error); diff --git a/src/apis/logout/logoutAxios.ts b/src/apis/logout/logoutAxios.ts new file mode 100644 index 00000000..e76fb710 --- /dev/null +++ b/src/apis/logout/logoutAxios.ts @@ -0,0 +1,20 @@ +import { isAxiosError } from 'axios'; + +import { privateInstance } from '@/apis/instance'; +import MESSAGES from '@/apis/messages'; + +const AUTH_URL = { + LOGOUT: '/api/auth/logout', +}; + +const userLogout = async () => { + try { + const response = await privateInstance.delete(AUTH_URL.LOGOUT); + return response.data; + } catch (error) { + if (isAxiosError(error)) throw error; + else throw new Error(MESSAGES.UNKNOWN_ERROR); + } +}; + +export default userLogout; diff --git a/src/components/SettingPage/LogOutBtn.tsx b/src/components/SettingPage/LogOutBtn.tsx index 38505d1e..c76a64c3 100644 --- a/src/components/SettingPage/LogOutBtn.tsx +++ b/src/components/SettingPage/LogOutBtn.tsx @@ -1,7 +1,23 @@ import styled from '@emotion/styled'; +import { useNavigate } from 'react-router-dom'; + +import userLogout from '@/apis/logout/logoutAxios'; function LogOutBtn() { - return 로그아웃; + const navigate = useNavigate(); + + const handleLogoutButton = async () => { + try { + await userLogout(); + localStorage.removeItem('accessToken'); + localStorage.removeItem('refreshToken'); + navigate('/'); + } catch (error) { + console.error(error); + } + }; + + return 로그아웃; } export default LogOutBtn;