Axios Interceptor로 accessToken갱신하기 (RefreshToken)

dev.horang🐯·2023년 2월 1일
2

기술로그

목록 보기
9/17

Refresh Token을 사용해서 access token을 갱신하는 방법은 여러가지가 있겠지만 나는 axios interceptor를 이용해서 갱신하는 로직을 사용했다.

axios interceptor은 말 그대로 axios통신을 할 때 가로 채서 중간에서 처리해 주는 과정을 말한다. request를 보낼 때 가로채거나 response를 받을 때 가로채는 방법 두가지가 있다.

나는 Refresh Token을 사용해서 response로 토큰 만료 메세지가 올 때 가로채서 재발급 받는 방식으로 진행했다.

내가 진행한 프로젝트의 경우 에러로그 최소화를 위해서 에러 처리도 모두 200값으로 들어왔기 때문에 모든 로직이 then에 존재한다.

restApi.interceptors.response.use(
  async (response) => {
    if (response?.data?.code == 40300) {
      const ip = '11.222.3333'
      const refresh_token = await getStorage("refreshToken")
      return await restApi.get(`/account/token?refreshToken=${refresh_token}&ipAddress=${ip}`)
    }
  },
)

response의 interceptor를 사용해서 code 40300(서버에서 정한 오류코드) 즉 토큰 만료에 대한 응답이 오게 되면 재발급 요청을 보낸다.

return await restApi.get(`/account/token?refreshToken=${refresh_token}`)
        .then(async (res) => {
          if (res.data.message === "OK") {
            setStorage("token", res.data.payload.access_token)
            originalRequest.headers.Authorization = `${res.data.payload.access_token}`;
            return axios(originalRequest);
          } 
        })

해당 axios 통신이 성공할 시에 토큰값을 다시 저장하고 원래 요청 하려고 했던 originalRequest의 헤더에 방금받은 토큰을 싣어서 보내면 클라이언트 뷰에서는 끊김없이 자동으로 토큰이 갱신되고 원래 요청 또한 보내지게 된다.

전체 코드

restApi.interceptors.request.use(
  async (config) => {
    const access_token = await getStorage("token")

    config.headers.common["Authorization"] = `Bearer ${access_token}`
    return config
  }
)

restApi.interceptors.response.use(
  async (response) => {
    const { config } = response;
    const originalRequest = config;

    if (response?.data?.code == 40300) {
      const refresh_token = await getStorage("refreshToken")
      return await restApi.get(`/account/token?refreshToken=${refresh_token}`)
        .then(async (res) => {
          if (res.data.message === "OK") {
            setStorage("token", res.data.payload.access_token)
            originalRequest.headers.Authorization = `${res.data.payload.access_token}`;
            return axios(originalRequest);
          } 

        }).catch((err) => {
          console.log(err)
        })
    }

    return response;
  },
  async (error) => {

    console.log(error, '^^***')
    throw error

  }
)
profile
좋아하는걸 배우는건 신나🎵

0개의 댓글