Axios interceptors 를 활용한 Refresh token 만료 시 처리 구현

Axios interceptors 를 활용한 Refresh token 만료 시 처리 구현

이슈

JWT refresh token 만료 시 로그인 페이지로 이동하지 않는 현상

문제점

refresh 토큰이 만료된 경우를 구분이 어렵다

access 토큰은 만료되었으나 refresh 토큰은 만료되지 않은 경우에 첫 요청은 실패하지만
react-query에서 3번 더 요청을 하기 때문에 두 번째 요청을 보내기 전에 next auth에서 refresh 토큰을 발급받아서 두 번째 요청은 성공했다

해결

Axios interceptors를 이용하여 3번째 재시도까지 토큰이 만료되었다는 응답을 받으면 refresh 토큰이 만료된 것으로 간주하고 로그인 페이지로 이동

구현 코드

import http, { setToken } from 'lib/axios';
import { route } from 'constants/route';
import { useEffect, useRef } from 'react';
import { getAxiosError } from 'utils/http';
import { ERROR_CODE } from 'constants/error';
import { isAxiosError } from 'axios';

const SessionLoader = ({ children }: { children: React.ReactNode }) => {
  // 각 요청에 대한 실패를 카운트하는 객체
  const responseInvalidTokenCounterRef = useRef<{ [key: string]: number }>({});

  useEffect(() => {
    http.interceptors.response.use(
      (response) => {
        // 응답 성공 시 카운트 초기화
        const requestUrl = response.config.url ?? 'common';
        responseInvalidTokenCounterRef.current[requestUrl] = 0;
        return response;
      },
      (error) => {
        if (isAxiosError(error)) {
          // 3번째 재시도까지 토큰이 유효하지 않을 때 로그인 페이지로 이동
          const requestUrl = error.config?.url ?? 'common';
          const errorData = getAxiosError(error);
          if (errorData?.result.errorCode === ERROR_CODE.INVALID_TOKEN) {
            responseInvalidTokenCounterRef.current[requestUrl] =
              responseInvalidTokenCounterRef.current[requestUrl] ?? 0;
            responseInvalidTokenCounterRef.current[requestUrl] += 1;
          }
          if (responseInvalidTokenCounterRef.current[requestUrl] > 2) {
            window.location.href = route.login;
          }
        }

        return Promise.reject(error);
      },
    );
  }, []);

  // 나머지 코드 생략...
  
  return <>{children}</>;
};
export default SessionLoader;

Read more

AI 세일즈 에이전트에게 도구를 줬더니: 추측에서 실제 조사로 전환한 B2B 파이프라인 구축기

AI 세일즈 에이전트에게 도구를 줬더니: 추측에서 실제 조사로 전환한 B2B 파이프라인 구축기

계속 우리를 괴롭혔던 문제 세일즈 파이프라인이 작동하고 있었습니다. 여섯 개의 Claude 에이전트가 각자 역할을 수행했습니다: 회사를 조사하고, 솔루션을 매핑하고, 제안서를 작성하고, 딜 규모를 추정하고, 이메일을 작성하고, 빠른 적합성 요약을 생성합니다. CLI 명령어 하나면 몇 분 안에 개인화된 세일즈 제안서가 완성되었습니다. 하지만 거기에는 거짓말이 내재되어 있었습니다. "리서처" 에이전트는 실제로 아무것도 조사하지

By Sardor Madaminov
배타적 서브타입(Exlusive Subtype) 테이블 설계와 백엔드 구현

배타적 서브타입(Exlusive Subtype) 테이블 설계와 백엔드 구현

배타적 서브타입이란? 데이터베이스 테이블 설계에서 슈퍼타입(Super Type)과 서브타입(Sub Type)은 공통 속성을 기준으로 엔티티(테이블)를 상위/하위로 나누는 데이터 모델링 기법입니다. * Super Type (상위 엔티티) * 여러 엔티티가 공통으로 가지는 속성을 모아 놓은 엔티티 * 식별자(PK, ID)를 포함한 공통 정보를 가지고 있음 * Sub Type (하위 엔티티)

By Plato Jung
A2A 메모리 레이어: AI 에이전트를 위한 공유 두뇌 구축하기

A2A 메모리 레이어: AI 에이전트를 위한 공유 두뇌 구축하기

모든 것의 시작이 된 문제 우리를 계속 괴롭히던 것이 있었습니다: 왜 AI 에이전트는 대화가 끝나는 순간 모든 것을 잊어버릴까요? 한번 생각해보세요. 챗봇에게 전화보다 이메일을 선호한다고 말합니다. 다음 세션에서는요? 마치 처음 만난 것처럼 행동합니다. 한 상담원에게 주문 문제를 설명하고, 다른 상담원에게 연결되면, 갑자기 처음부터 다시 시작해야 합니다. 우리 모두 겪어본 일입니다.

By Sardor Madaminov
[시리즈 2편] 실무로 배우는 메시지 큐 - RabbitMQ

[시리즈 2편] 실무로 배우는 메시지 큐 - RabbitMQ

들어가며 [시리즈1]에서는 프로세스 내부 메시지 큐를 다뤘습니다. 이번엔 네트워크 메시지 큐인 RabbitMQ를 다룹니다. RabbitMQ 공식 문서나 기술 블로그는 많지만, 실무에서 어떻게 사용하는지에 대한 글은 의외로 적습니다. "Producer가 뭐고 Consumer가 뭔지는 알겠는데, 그래서 실제로는 어떻게 쓰는데?" 이번 글에서는 우리 MES 시스템에서 RabbitMQ를 어떻게 활용하고 있는지 실제 코드와 함께 공유합니다. 우리

By Jeonggil