[React] axios interceptor로 refresh token 발급하기

차슈·2024년 11월 8일
0

REACT

목록 보기
15/16
post-thumbnail

Axios Intereptor를 활용하고, refreshToken을 활용해서 acessToken을 재발급 받는 로직을 구현하였다.

refreshToken을 활용하여, 토큰 재발급을 진행하면, 생기는 장점

보안성 향상

Access token은 상대적으로 짧은 유효 기간을 가지기 때문에, 만료 후 재발급이 필요하다. RefreshToken을 통해 만료된 토큰을 도용하는 것을 방지하고, 자주 재발급을 진행하여 더 안전하게 세션을 관리할 수 있다.


request시, 따로 body로 데이터 전송을 안해주어도 되고, 로그인 시 얻는 Refresh 토큰을 헤더에 Bearer 형태로 넘겨준다.

Authorization: Bearer refreshToken

axiosInstace라는 api hook을 따로 만들어서 코드를 짰다.

import axios from 'axios';

const axiosInstance = axios.create({
  baseURL: 'baseurl'
});

axiosInstance.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('AccessToken');
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

axiosInstance.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;

    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;

      try {
        const refreshToken = localStorage.getItem('RefreshToken');

        const response = await axios.post('연결된 url', null, {
          headers: { Authorization: `Bearer ${refreshToken}` }
        });

        const { accessToken } = response.data;

        localStorage.setItem('AccessToken', accessToken);

        originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;

        return axiosInstance(originalRequest);
      } catch (refreshError) {
        console.error('리프레시 토큰 오류:', refreshError);

        localStorage.removeItem('AccessToken');
        localStorage.removeItem('RefreshToken');
        window.location.href = '/login';
        return Promise.reject(refreshError);
      }
    }

    return Promise.reject(error);
  }
);

export default axiosInstance;

그리고 로그인 부분에 axios.post 대신에 axiosInstance.post로 불러온다. 처음에 로그인에서 불러오지 않아서 코드를 짰음에도 불구하고 제대로 작동되지 않았다.

    const response = await axiosInstance.post('/auth/login', {
            email: values.email,
            password: values.password,
    })

이 부분은 User의 정보를 받아오는 부분인데, 맨 처음에 로그인 대신에 유저를 받아오는 부분에서 instance를 사용하였더니 토큰이 재발급이 제대로 진행되지 않았다.
로그인과 유저 정보 받아오는 부분 둘 다! axiosInstance로 받아와야한다.

  const response = await axiosInstance.get('/user/me', {
    headers: {
      Authorization: `Bearer ${token}`
    }
  });
  return response.data;
};

0개의 댓글