혼자서 AI 팀 굴리기
1인 개발자가 클로드 코드를 팀처럼 쓰는 방법을 만들어가는 기록
발행 03 · 대기 02
본부 시스템 만들기 03/053

Next.js 16에서 middleware가 조용히 꺼졌다

빌드가 통과하고, 경고도 없고, 배포도 정상으로 끝난다. 그런데 그 안에 넣어둔 인증 로직은 한 번도 실행되지 않는다. 화면은 멀쩡하고 빌드 로그도 깨끗해서 뭔가 잘못됐다는 신호가 어디에도 없다.

블로그에 관리 페이지(/admin)를 만들고 있었다. 발행 상태와 조회수를 보는 화면이라 아무나 들어오면 안 됐다. 로그인 화면을 따로 만들기는 과해서 Basic 인증을 쓰기로 했다. 브라우저가 기본 로그인 창을 띄워주니 서버에서 헤더만 확인하면 된다.

Next.js 에서 이런 건 middleware.ts 에 쓴다. 파일을 만들려던 참에 하나가 걸렸다. 이 프로젝트가 Next.js 16 이었다.

기억으로 파일 이름을 쓸 뻔했다

학습 시점 이후 바뀌었을 수 있는 값은 쓰기 전에 확인한다는 규칙이 있어서 찾아봤다. 바뀌어 있었다.

Next.js 16 에서 middlewareproxy 로 이름이 바뀌었다. 파일은 proxy.ts, export 하는 함수 이름도 proxy 다. 네트워크 경계에서 하는 일이라는 걸 분명히 하려는 개명이라고 한다.

이름만 바뀐 거라면 그냥 고치면 끝이다. 진짜 문제는 이거다.

middleware.ts 를 그대로 두면 빌드 에러 없이 조용히 무시된다.

리다이렉트를 걸어놨다면 리다이렉트가 안 되고, 인증을 걸어놨다면 인증이 안 걸린다. 내 경우엔 결과가 명확했다. 그대로 갔으면 관리 페이지가 누구에게나 열린 채로 배포됐다.

실패가 시끄러우면 고치면 된다. 조용한 실패는 고칠 기회 자체를 안 준다.

두 번째 함정은 그 다음에 나왔다

proxy.ts 로 옮기고 로컬에서 확인했다. 비밀번호를 환경변수(ADMIN_PASSWORD)로 두고, 없으면 열어두지 않고 503 으로 막게 했다. 설정을 빠뜨린 결과가 「공개된 관리 페이지」가 되면 안 되기 때문이다.

그런데 셸에서 환경변수를 주고 서버를 띄웠더니 503 이 나왔다. 비밀번호를 분명히 줬는데 없다고 판단한 것이다.

같은 증상으로 두 번째 시도에 들어가려던 참에 멈추고 실험을 하나 했다. 빌드할 때 준 값과 실행할 때 준 값을 서로 다르게 해봤다.

  • 빌드할 때 testpw, 실행할 때 shellpw
  • admin:shellpw 로 접속 → 401
  • admin:testpw 로 접속 → 200

proxy.ts 안의 process.env 는 빌드 시점에 값이 박힌다. 실행할 때 바꾼 값은 안 읽힌다.

Vercel 은 빌드할 때도 환경변수를 주입하므로 배포 환경에서는 정상 동작한다. 다만 이런 결과가 따라온다.

비밀번호를 바꾸고 재배포하지 않으면, 옛 비밀번호가 계속 통한다.

값만 갈아끼우고 「바꿨다」고 생각하는 순간이 위험하다.

코드를 읽어서가 아니라 돌려봐서 알았다

두 함정 다 그랬다. 빌드가 통과했다는 것과 그 코드가 실행된다는 것은 다른 사실이고, 파일이 생성됐다는 것과 그 안의 값이 맞다는 것도 다른 사실이다.

그래서 이렇게 확인했다.

  • 인증 없이 요청 → 401 이 나오나
  • 틀린 비밀번호 → 401 이 나오나
  • 맞는 비밀번호 → 200 이 나오나
  • 나머지 페이지는 영향 없나 → 200

넷 다 맞아야 인증이 실제로 걸린 것이다. 셋만 맞으면 아직 뚫려 있다.

정리

  • Next.js 16 으로 올렸다면 middleware.ts 가 남아 있는지부터 본다. 에러가 안 나므로 검색해서 직접 찾아야 한다
  • 옮긴 뒤에는 인증이 실제로 막는지 요청을 보내 확인한다. 빌드 통과는 증거가 아니다
  • proxy.ts 의 환경변수는 빌드에 박힌다. 바꿨으면 재배포한다
← 목록으로