1+
2+ import { RefreshResponse } from '@/models/auth'
13import ky from 'ky'
24
5+ // 리프레시 토큰용 별도 클라이언트 생성
6+ const refreshClient = ky . create ( {
7+ prefixUrl : process . env . NEXT_PUBLIC_API_URL ,
8+ timeout : 10000 ,
9+ } )
10+
11+ // 토큰 갱신 중임을 나타내는 Promise를 저장
12+ let refreshTokenPromise : Promise < RefreshResponse [ 'data' ] > | null = null
13+
314export const kyClient = ky . create ( {
415 prefixUrl : process . env . NEXT_PUBLIC_API_URL , // Base URL 설정
516 timeout : 10000 , // 타임아웃 설정
@@ -13,17 +24,53 @@ export const kyClient = ky.create({
1324 } ,
1425 ] ,
1526 afterResponse : [
16- ( _request , _options , response ) => {
17- // 예: 로깅 처리
18- console . log ( `Response: ${ response . status } ${ response . url } ` )
27+ async ( request , options , response ) => {
28+ if ( response . status === 511 ) {
29+ try {
30+ // 이미 진행 중인 토큰 갱신이 있다면 그 Promise를 재사용
31+ if ( ! refreshTokenPromise ) {
32+ refreshTokenPromise = ( async ( ) => {
33+ const accessToken = localStorage . getItem ( 'accessToken' )
34+ const refreshToken = localStorage . getItem ( 'refreshToken' )
35+
36+ const response = await refreshClient
37+ . post ( 'auth/refresh' , {
38+ headers : {
39+ 'Content-Type' : 'application/json' ,
40+ } ,
41+ json : { accessToken, refreshToken } ,
42+ } )
43+ . json < RefreshResponse > ( )
44+
45+ localStorage . setItem ( 'accessToken' , response . data . accessToken )
46+ localStorage . setItem ( 'refreshToken' , response . data . refreshToken )
47+
48+ return response . data
49+ } ) ( )
50+ }
51+
52+ // 토큰 갱신 완료 대기
53+ const newTokens = await refreshTokenPromise
54+ refreshTokenPromise = null // 갱신 완료 후 초기화
55+
56+ // 원래 요청을 새 토큰으로 재시도
57+ return ky ( request , {
58+ ...options ,
59+ headers : {
60+ ...options . headers ,
61+ Authorization : newTokens . accessToken ,
62+ } ,
63+ } )
64+ } catch ( error ) {
65+ refreshTokenPromise = null // 에러 발생 시에도 초기화
66+ console . error ( '리프레시 토큰 갱신 실패:' , error )
67+ localStorage . removeItem ( 'accessToken' )
68+ localStorage . removeItem ( 'refreshToken' )
69+ throw new Error ( '리프레시 토큰 만료' )
70+ }
71+ }
1972 } ,
2073 ] ,
21- // beforeError: [
22- // (error) => {
23- // console.error(error.message)
24- // return error
25- // },
26- // ],
2774 } ,
2875} )
2976
0 commit comments