Access Token 만료시 일관적인 401 에러 응답 처리 Thumbnail

with Axios Interceptor

4 min read
인증

Access Token 만료시 일관적인 401 에러 응답 처리

이 글은 노션에서 마이그레이션된 글입니다.

섬네일섬네일

배경 및 목적

애플리케이션에서 보호된 리소스에 접근할 때 발생하는 401 인증 에러에 대한 일관된 처리 방식이 필요했다. 특히 액세스 토큰 만료 시 리프레시 토큰을 통한 재발급 과정과 이에 따른 요청 재시도 로직을 효율적으로 구현하고자 했다.

해결 과제

기존 방식에서는 다음과 같은 복잡한 프로세스가 필요했다:

  1. 보호된 리소스 접근 요청
  2. 401 에러 발생 시 리프레시 토큰으로 새 액세스 토큰 발급 요청
  3. 원래 요청 재시도

이러한 다중 요청 처리는 마치 데이터베이스의 트랜잭션과 같은 복잡성을 가지고 있어 효율적인 해결책이 필요했다.

구현 방안

Axios 인스턴스의 인터셉터 기능을 활용하여 모든 401 에러에 대한 일관된 처리 로직을 구현했다. 주요 처리 절차는 다음과 같다:

  1. 401 에러가 발생한 원본 요청을 저장
  2. 리프레시 토큰을 사용하여 새로운 액세스 토큰 발급 요청
  3. 토큰 재발급 성공 시 원본 요청 재시도
  4. 실패 시 세션 만료로 판단하고 로그인 페이지로 리다이렉트

axios interceptor

import axios, { AxiosError } from "axios";
import { refreshAccessToken } from "@/api/user/auth.ts";
import useAuthStore from "@stores/useAuthStore.ts";

export const api = axios.create({
  timeout: 5000,
  withCredentials: true,
});

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

    if (error.response?.status === 401) {
      try {
        const response = await refreshAccessToken();
        if (response.data.success) {
          return axios(originalRequest!);
        }
      } catch (error) {
        console.error("토큰 재발급 실패", error);
        alert("세션이 만료되었습니다. 다시 로그인해주세요.");
        useAuthStore.persist.clearStorage();
        window.location.href = "/login";
        return Promise.reject(error);
      }
    }
    return Promise.reject(error);
  }
);

개선 효과

  1. 사용자 경험 향상
    • 토큰 만료 시에도 서비스 이용의 연속성 보장
    • 최소한의 지연으로 자동 토큰 재발급 처리
    • 세션 만료 시 명확한 안내와 함께 로그인 페이지로 유도
  2. 개발 효율성 증대
    • 401 에러 처리 로직의 중앙화로 코드 중복 제거
    • 일관된 에러 처리로 유지보수성 향상
    • 개별 컴포넌트에서의 토큰 관리 부담 감소

유연성 확보

특정 요청에 대해 다른 방식의 401 에러 처리가 필요한 경우, Axios 인스턴스 대신 일반 Axios를 사용하면 되어 유연하게 응답 처리를 할 수 있다는 점이 좋았다.

결론

Axios 인터셉터를 활용한 401 에러 처리 방식은 복잡한 토큰 갱신 프로세스를 효율적으로 처리하며, 사용자 경험과 코드 품질을 동시에 개선하는 효과적인 해결책이 되었다.

📌 Table of Contents

0
추천 글