nextjs 401 에러 재인증 처리하기 2편
22 Oct 2025 | memo nextjs authentication middleware app-router1편에서는 Next.js App Router 환경에서 SSR 렌더링이 시작되기 전에 토큰을 리프레시하는 미들웨어 방식을 다뤘다.
이번 글에서는 그 구조가 가진 race condition 문제와, 이를 해결하기 위한 클라이언트 주도형 리프레시 접근을 정리한다.
미들웨어 사전 리프레시의 한계
1편에서 사용한 방식은 렌더링 전에 토큰을 갱신해 SSR을 안정적으로 보장하는 구조였다.
하지만 이 방식은 여러 요청이 동시에 들어오는 상황에서 심각한 부작용을 일으킬 수 있다.
팀장님께선 이 문제를 아래와같이 설명해주셨다.
“간단한 서비스는 이게 큰 문제가 되지는 않아서 사용자 경험이나 SEO를 생각해 사전리프레시를 하기도 하는 것 같은데, 우리가 개발하려는 사이트는 분산 시스템으로서 동시에 여러 서버 액션을 호출한다던가 하는 일이 잦을 수 있어 이 문제가 걱정스러운 수준까지 커질 수 있다고 생각합니다.”
문제 상황: race condition
race condition = 여러 요청이
동시에동일한 자원(여기서는 refreshToken)에 접근해, 실행 순서에 따라 결과가 달라지는 불안정한 상태
예시
/dashboard,/me,/notifications페이지를 동시에 요청- accessToken이 만료되어 있음
- 각 요청의 미들웨어가
각자 동시에/auth/restore-token호출 - 첫 번째 요청만 성공하고, 나머지는 “이미 사용된 refreshToken”으로 실패
- 실패한 요청들이
/login으로 리다이렉트 - 브라우저는 리다이렉트 루프에 빠짐 🔁
- 심한 경우 요청이 O(n²) 수준으로 증식 → 서버 과부하
단일 서버에서는 눈에 잘 안 띄지만, 분산 시스템(예: 아몬드영 구조)에서는 쉽게 재현되는 문제다.
클라이언트 주도형 리프레시 (벨로그의 어떤분이 제안한 방식)
이 문제를 해결하기 위해 리프레시 주도권을 클라이언트로 옮긴 구조가 현재 시간을 아끼는 방법중 가장 베스트로 채택되었다.
즉, 401을 받은 후 클라이언트가 재요청하는 구조다.
흐름 요약
- 서버에서 401 발생
- 클라이언트의 axios interceptor가 이를 감지
/auth/restore-token요청- 새 accessToken 발급 후 원래 요청을 재시도
- 성공 시 쿠키 동기화 완료
앉았으니, 해보는 거죠