🚧 문제 상황
⚙️ 발생한 환경 및 프로그램
`next.js ^16.1.16` , `배포 서버 - 로컬 프론트`
🎯 문제 상황 정의
Next.js 16의 `proxy.ts`를 도입하여 인증 토큰 검증 로직을 추가했을 때, 로컬 개발 환경(`localhost:3000`)에서 배포된 백엔드 서버와 통신하는 구조에서 로그인을 하면 login API가 배포/로컬 url로 각각 호출(총 2번) 되며 계속 `/auth/login`으로 튕기는 문제가 발생하였다.


🔥 발생한 문제 및 에러
- 로그인 API는 200 응답을 받고 쿠키도 브라우저 Application 탭에 저장되는 것을 확인
- 하지만 `router.push("/")`로 이동 시 미들웨어가 토큰이 없다고 판단하여 `/auth/login`으로 리다이렉트
- Network 탭에서 `/series` 접근 시 307 리다이렉트로 다시 `/auth/login`으로 튕기는 것 확인
- 새로고침 시 쿠키가 사라지는 것처럼 보이는 현상 발생
🧭 해결방안 및 과정
💼 해결하기 위한 노력 및 시행착오
1. `proxy.ts`의 파일 위치
→ `/src/proxy.ts`로 제대로 된 위치에 있었다.
2. rewrites (`next.config.ts`) 시도
→ env 설정 문제로 문제가 해결되지 않았다.
3. 개발자도구 - [Application]에서 쿠키의 domain 값 확인 (잡았다)
→ 배포 url로 고정이 되어 있었다. 백엔드 코드를 확인해 보니 쿠키를 생성할 때 아래처럼 배포 도메인명을 하드코딩하여 Domain 값을 설정하고 있었다.
ResponseCookie cookie = ResponseCookie.from(name, value)
.domain("도메인명")
💡 근본 원인 파악
3번이 원인이었으며, 브라우저의 쿠키는 Domain 속성에 따라 전송되는 범위가 결정된다.
배포 도메인명으로 고정된 Domain 값으로 설정하는 경우, 브라우저는 해당 쿠키를 지정된 도메인에서만 전송하기 때문에 로컬 프론트 환경에서는 해당 쿠키를 포함하지 않았다.
즉, local에서 백엔드 요청 시 브라우저는 accessToken / refreshToken 쿠키를 전송하지 않았고, proxy에서는 '토큰이 없는 상태'로 판단하게 되어 로그인 이후에도 계속 로그인 페이지로 튕기는 현상이 발생하였다.
또한 Network 탭에서는 다음과 같은 현상이 관찰되었다.
/series → 307 redirect → /auth/login
이는 proxy.ts의 인증 검증 로직이 정상적으로 동작했지만 쿠키가 전달되지 않아 인증 실패로 처리된 것이었다.
💫 최종 해결 방법
개발 환경에서는 로컬 프론트와 배포 서버 간 쿠키 도메인 불일치가 발생하기 때문에 로컬에서 작업하는 경우 proxy에서 토큰 검증을 수행하지 않도록 분기 처리하였다.
이때 백엔드에서 Domain을 하드코딩하여 설정한 것은 보안상 올바른 설정이므로 유지하고자 하였다.
export function proxy(request: NextRequest) {
const isDev = process.env.NODE_ENV === "development";
if (isDev) {
return NextResponse.next();
}
const accessToken = request.cookies.get("accessToken")?.value;
if (!accessToken) {
return NextResponse.redirect(new URL("/auth", request.url));
}
return NextResponse.next();
}
여기서 `process.env.NODE_ENV` 는 구동 환경 체크용 환경변수이고 development인 경우 개발 환경, production인 경우 배포 환경을 나타낸다.
위와 같이 구현하여 개발 환경 (local) 에서는 토큰 검증을 하지 않도록 코드를 구성하였다.
정리하자면,
개발 환경에서는 1) 토큰 검증을 스킵 → 2) 정상적으로 페이지 이동 가능
배포 환경에서는 1) 동일 도메인에서 쿠키 전달 → 2) proxy.ts에서 정상적으로 토큰 인증 검증 수행
하도록 구성하였다.
👾 결론
이전 프로젝트를 진행할 때는 큰 문제없이 쉽게 middleware를 구현했었다. 지금 와서 생각해 보니 배포 서버가 아닌, 로컬 서버로 연동을 하였기 때문에 문제가 발생하지 않았던 것이었다.
또한 다른 배포서버가 있는 프로젝트도 백엔드의 Domain 설정과 middleware 코드를 뜯어보았다.
middleware는 지금과 동일한 구조로 작성되어 있었는데, 백엔드의 Domain에서 도메인을 따로 지정해주지 않고 브라우저가 요청한 도메인으로 자동 설정되고 있어서 이와 같은 에러가 발생하지 않았던 것이었다!
이러한 차이점으로 인해 에러를 찾기 쉽지 않았다. 구글링을 해봐도 많은 자료가 있지 않아서 약간 애를 먹었다.
이런 경험을 통해 백엔드에서 쿠키에 토큰을 저장할 때 Domain을 지정하냐/하지 않느냐에 따라 보안상의 중요성도 알게 되었다.
📚 참고자료
[Next.js] middleware가 쿠키를 못 읽는 이유? Secure와 HTTPS의 함정
#Next.js #pN룰 #디자인시스템 #Middleware #HTTPS #MUI #BDS #Playwright #CSRF ✅ BDS + MUI 마이그레이션 중 겪은 middleware 디버깅 & 코드리뷰 회고현재 프로젝트는 Buzzle Design System (BDS)과 MUI를 기반으로 한 디자인
dingx2-story.tistory.com
'트러블슈팅' 카테고리의 다른 글
| [HTML, CSS] <input type="password"> 시 기호(*)가 보이지 않는 문제 (나눔스퀘어) (0) | 2025.12.07 |
|---|---|
| [Next.js] 메타데이터 적용이 안되는 문제 해결 (ft. Streaming Metadata, Lighthouse) (0) | 2025.12.04 |
