액세스 토큰 만료 시 갱신 로직
원래 구현하려고 했던 로직
액세스 토큰을 헤더에 추가해서 요청 보냄 → fetch interceptor → 요청에 들어있는 액세스 토큰이 만료됐는지 payload 디코딩 해서 판단 → 만료됐으면 액세스 토큰 갱신 요청 후 업데이트된 액세스 토큰을 헤더에 다시 실어줌 → 정상적으로 원래 요청 응답
interceptor 란 : 요청 시에 요청을 가로채거나 응답을 가로채서 추가적인 작업을 할 수 있게 해주는 기능
fetch 에는 기본적으로 interceptor 기능을 제공하고 있지 않음 (axios에서는 interceptor 기능 제공)
그럼 어떻게 인터셉터 구현? → window 객체의 fetch 객체를 잡아와서 async 로 비동기적으로 안에서 작업해주는 느낌…. 설명을 어떻게 해야하지
<aside> 💡 즉! window 객체 안의 fetch 객체 안의 어떤 요청 함수가 실행되기 전에 async 로 args 를 가져와서 추가적인 작업을 해주는 개념! 응답을 수정해서 리턴할 수도 있음
</aside>
모듈로 분리해서 사용 → next.js 에서는 서버 사이드와 클라이언트 사이드가 있어서 하나의 파일로 적용하는 것은 힘들었다… → 결론적으로는 서버 사이드 / 클라이언트 사이드 interceptor 따로 모듈화 해서 각각 적용 시키는게 맞을 것 같음
내가 한거 : 우리는 응답을 가로채서 작업을 해야할 상황이 액세스 토큰에 관련한 부분밖에 없었음. 액세스 토큰은 클라 사이드에서 관리해서(localstorage에 저장) 클라 사이드 interceptor 만 구현해서 적용함
export default function responseInterceptor() {
const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
let [resource, options] = args;
const response: Response = await originalFetch(resource, options);
if (response.status === 401) {
const res2 = await fetch(
`${process.env.NEXT_PUBLIC_API_SERVER}/auth/newToken`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${localStorage.getItem('refreshToken')}`,
},
},
);
if (res2.status === 200 || res2.status === 201) {
const data = await res2.json();
const newAccessToken = data.accessToken;
localStorage.removeItem('accessToken');
localStorage.setItem('accessToken', newAccessToken);
const result: Response = await originalFetch(resource, {
...options,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${newAccessToken}`,
},
});
return result;
} else {
return res2;
}
} else {
return response;
}
};
}
fetch 요청 후 데이터 컨트롤
서버 사이드, 클라이언트 사이드 어떻게 구분했는지
라이브러리 뭐 썼는지