아이패드 크롬에서만 로그인이 안 돼요 — nginx, 로드밸런서, 그리고 사라진 https

 "갤럭시 패드 크롬은 되고요, 아이패드 사파리도 되는데, 아이패드 크롬만 로그인이 안 돼요."

  운영하다 보면 이런 신고가 제일 골치 아픕니다. 특정 브라우저, 특정 기기에서만 재현되는 버그. 코드를 아무리 들여다봐도 "브라우저마다 다르게 동작할 이유"가 안 보이거든요. 이 글은 그 신고 한 건이 사실은 nginx가 로드밸런서 뒤에서 https를 http로 떨어뜨리던 고전적인 인프라 함정이었다는 걸 추적한 기록입니다.

  증상 : 관리자 대시보드에서 다른 시스템으로 넘어가는 로그인 버튼이 있는데, 이게 특정 환경에서만 실패했습니다.

 아이패드 크롬  :  실패,  아이패드 사파리 : 성공

 갤럭시탭 크롬 :  성공

 PC: 성공

   "크롬 문제다"라고 단정하기엔 갤럭시 크롬은 멀쩡합니다. "iOS 문제다"라고 하기엔 사파리는 됩니다. 딱 iOS × 크롬 교집합에서만 터집니다.


  로그를 나란히 놓고 본다


  증상이 아니라 데이터를 봅니다. 백엔드 referer 검증 로그를 실패/성공 케이스로 나란히 놓으니 결정적 차이가 한 줄에 드러났습니다.


  아이패드 크롬 (실패):

  referer: http://app.example.com/        ← http, 그리고 루트 경로

  허용목록: ['https://admin.example.com/', 'https://app.example.com/']

  → referer 체크 후 리다이렉트 (301, 로그인 차단)


  아이패드 사파리 (성공):

  referer: https://app.example.com/   ← https, 정상 경로

  → 통과, 정상 로그인 진행


  검증 코드는 단순했습니다.


  허용 목록은 전부 https://로 시작합니다. 그런데 아이패드 크롬이 보낸 referer는 http://. 

  즉 *"크롬이 로그인을 못 한다"*가 아니라 *"크롬은 페이지를 http로 보고 있다"*가 진짜 질문이었습니다.

  왜 크롬만 http로 볼까

  로그인 직후 리다이렉트 체인을 한 줄씩 따라가니, 같은 301 응답 직후 두 브라우저가 갈라졌습니다.


  - 크롬: 리다이렉트 다음 요청의 referer가 - (없음) → 이후 모든 요청 referer가 http://app.example.com... (페이지 자체가 http로 로딩됨)

  - 사파리: 같은 요청 referer가 https://... 유지 → 끝까지 https


  https → http로 내려갈 때 브라우저는 보안상 referer를 제거합니다. 크롬에서 referer가 -로 찍힌 것은 그 지점에서 프로토콜이 다운그레이드됐다는 증거였습니다. 사파리·갤럭시 크롬은 HSTS 자동 업그레이드(http를 https로 올려서 요청)가 동작해     

  다운그레이드가 일어나지 않았고, iOS 크롬은 별도 HSTS 캐시라 그 항목이 없어 http를 그대로 따라간 겁니다.


 여기서 "지난주는 됐는데 이번주부터 안 된다"의 답도 나옵니다. 서버 코드는 안 바뀌었습니다(git으로 확인). 바뀐 건 그 기기의 HSTS 캐시 상태입니다. 캐시 삭제나 크롬 업데이트로 자동 업그레이드가 풀리면, 몇 달 전부터 잠복해 있던 서버 버그가 그제서야 드러납니다.


  진짜 범인: nginx의 절대 리다이렉트


  해결: absolute_redirect off;


  nginx가 절대 URL을 조립하지 않게 하면, Location은 상대경로로 나갑니다.


  http {

      absolute_redirect off;

     ...

  }

적용 후 정상 동작

  

댓글