대머리개발자

JWT 사실 어려운 친구였다. 본문

개발이야기/개념

JWT 사실 어려운 친구였다.

대머리개발자 2024. 4. 26. 16:13
728x90

 

JWT가 만료되는시점에 페이지가 새로고침되어 

페이지 내에 속한 모든 API가 호출되면

모든 API에 대해서 토큰 갱신 작업을 진행한다. 

3번의 리프레쉬 토큰 갱신 API가 콜된다. ㅜㅜ

 

최초의 요청이 토큰이 만료되면

두번째, 세번째, .. 요청은 대기를 하고 순차적으로 처리한다. 즉 직렬화 한다!

 

최초 요청에 토큰을 갱신하고 갱신한 값으로 두번째, 세번째, .. 요청을 처리 할 수 있도록 한다!!

 

방법은 큐와 인터셉터 이용한다.

 

request, response 둘 중 하나의 인터셉터를 이용 하면 된다.

request를 이용하기로 했다. 

 

응답으로 온 401 결과를 처리하는 것보다는 request를 이용해서  "보내기 전"에 만료 체크를해서

애초에 요청을 보내지 않으면 한 번이라도 네트워크 비용을  cut 할 수 있다.


function subscribeTokenRefresh(cb: (newToken:string) => void) {
    subscribers.push(cb)
}

function onRefreshed(token:string) {
    subscribers.map(cb => cb(token))
    subscribers = []
}

instance.interceptors.request.use(async config => {
    const currentToken = localStorage.getItem('access_token');
    config.headers['Content-Type'] = 'application/json'

    if(currentToken){
         config.headers['Authorization'] = `Bearer ${currentToken}`
        //토큰이 만료되었다면 새로운 토큰을 요청하자!!
        const expiry = jwtDecode<any>(currentToken).exp
        if(expiry * 1000 <= new Date().getTime()){
            if (isRefreshing) {
                return new Promise((resolve, reject) => {
                    subscribeTokenRefresh((newToken) => {
                        config.headers['Authorization'] = 'Bearer ' + newToken
                        resolve(axios(config))
                    })
                })
            }else{
                isRefreshing = true
                 refreshToken().then((newToken) => {
                    config.headers['Authorization'] = `Bearer ${newToken}`
                    onRefreshed(newToken)
                    return config;
                }).catch((error) => {
                    localStorage.setItem('access_token', '')
                    localStorage.setItem('refresh_Token', '')
                }).finally(() => {
                    isRefreshing = false;
                });
            }
        }
    }
    return config;

});

 

최초 리프레쉬토큰으로 요청하고 응답이 오면 newToken을 가지고 두번째, 세번째, ... 요청을 진행하는 것이다!!

 

깔끔스 하다!!! 좋았다!!

 

 

 

 

728x90

'개발이야기 > 개념' 카테고리의 다른 글

비동기와 논블로킹, 리액티브  (0) 2024.06.07
리액터 병렬 처리  (0) 2024.05.10
Json 안에 Json 처리  (0) 2024.04.25
네이밍 너무 힘들다.  (1) 2024.04.19
Armeria를 사용하는 이유  (0) 2024.03.12