1- import axios from 'axios' ;
1+ import axios from "axios" ;
2+ import Cookies from "js-cookie" ;
3+ import { refreshAccessToken } from "../services/authService" ;
24
35const getApiBaseUrl = ( ) => {
4- const baseUrl = import . meta. env . VITE_BASE_DEV_URL ; // 개발 서버 URL
5-
6- // URL이 '/'로 끝나면 'api/', 아니면 '/api/'
7- return baseUrl . endsWith ( '/' ) ? `${ baseUrl } api/` : `${ baseUrl } /api/` ;
6+ const baseUrl = import . meta. env . VITE_BASE_URL ;
7+ return baseUrl . endsWith ( "/" ) ? `${ baseUrl } api/` : `${ baseUrl } /api/` ;
88} ;
99
1010const API_BASE_URL = getApiBaseUrl ( ) ;
1111
1212const apiConfig = axios . create ( {
1313 baseURL : API_BASE_URL ,
14- timeout : 5000 , // 요청 타임아웃 5초
14+ timeout : 5000 ,
1515 headers : {
16- ' Content-Type' : ' application/json' ,
16+ " Content-Type" : " application/json" ,
1717 } ,
18+ withCredentials : true ,
1819} ) ;
1920
20- export default apiConfig ;
21+ // 요청 인터셉터: 모든 요청에 자동으로 엑세스 토큰 추가
22+ apiConfig . interceptors . request . use (
23+ ( config ) => {
24+ const accessToken = localStorage . getItem ( "accessToken" ) ;
25+ if ( accessToken ) {
26+ config . headers . Authorization = `Bearer ${ accessToken } ` ;
27+ }
28+ return config ;
29+ } ,
30+ ( error ) => Promise . reject ( error )
31+ ) ;
32+
33+ // 401 발생 시 자동으로 토큰 재발급 후 요청 재시도
34+ apiConfig . interceptors . response . use (
35+ ( response ) => response ,
36+ async ( error ) => {
37+ const originalRequest = error . config ;
38+
39+ // 401 Unauthorized 발생 시, 자동으로 토큰 재발급
40+ if ( error . response ?. status === 401 && ! originalRequest . _retry ) {
41+ originalRequest . _retry = true ;
42+
43+ try {
44+ const refreshToken = Cookies . get ( "refreshToken" ) ; // 쿠키에서 리프레시 토큰 가져오기
45+ if ( ! refreshToken ) {
46+ console . error ( "리프레시 토큰 없음 → 재로그인 필요" ) ;
47+ localStorage . removeItem ( "accessToken" ) ;
48+ Cookies . remove ( "refreshToken" ) ;
49+ window . location . href = "/login" ; // 로그인 페이지로 이동
50+ return Promise . reject ( error ) ;
51+ }
52+
53+ // ✅ 엑세스 토큰 재발급 요청
54+ const newTokens = await refreshAccessToken ( localStorage . getItem ( "accessToken" ) ! ) ;
55+ localStorage . setItem ( "accessToken" , newTokens . accessToken ) ;
56+ Cookies . set ( "refreshToken" , newTokens . refreshToken , { secure : true , sameSite : "Strict" } ) ;
57+
58+ // ✅ 새로운 토큰으로 원래 요청 다시 실행
59+ originalRequest . headers . Authorization = `Bearer ${ newTokens . accessToken } ` ;
60+ return apiConfig ( originalRequest ) ;
61+ } catch ( refreshError ) {
62+ console . error ( "토큰 갱신 실패 → 재로그인 필요" ) ;
63+ localStorage . removeItem ( "accessToken" ) ;
64+ Cookies . remove ( "refreshToken" ) ;
65+ window . location . href = "/login" ; // 로그인 페이지로 이동
66+ return Promise . reject ( refreshError ) ;
67+ }
68+ }
69+
70+ return Promise . reject ( error ) ;
71+ }
72+ ) ;
73+
74+ export default apiConfig ; // ✅ 모든 API 요청에서 사용 가능!
0 commit comments