refresh token

액세스 토큰 만료 시 갱신 로직

  1. 원래 요청 응답이 401 이면 갱신 하는 요청을 보내서 액세스 토큰 업데이트 후 다시 재요청
  2. 프론트 측에서 토큰 만료시간을 계산해서(jwt token payload 디코딩) 만료됐을 때에만 요청

원래 구현하려고 했던 로직

액세스 토큰을 헤더에 추가해서 요청 보냄 → fetch interceptor → 요청에 들어있는 액세스 토큰이 만료됐는지 payload 디코딩 해서 판단 → 만료됐으면 액세스 토큰 갱신 요청 후 업데이트된 액세스 토큰을 헤더에 다시 실어줌 → 정상적으로 원래 요청 응답

fetch interceptor

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;
    }
  };
}

nextjs data fetching

fetch 요청 후 데이터 컨트롤

서버 사이드, 클라이언트 사이드 어떻게 구분했는지

라이브러리 뭐 썼는지