Spring Boot + Nginx 환경에서 redirect 시 HTTPS가 HTTP로 변경되는 문제 해결하기

2025. 4. 21. 21:31·Error Log

안녕하세요!

최근 서버 개발을 하면서 발생했던 트러블 슈팅과 왜, 무엇이 원인이였는지 공유하고자 합니다.

 

현 상황은 이러했습니다.

사용자는 HTTPS로 웹 애플리케이션에 접속하여 일명 PRG(Post Redirect Get) 프로세스를 진행하고 있었습니다.

Post 요청 후 Spring Boot 애플리케이션은 사용자를 결과 페이지로 리디렉션하도록 설계되어 있었습니다.

그러나 사용자가 Safari 브라우저를 사용할 때는 아래의 사진처럼 '사파리가 해당 페이지를 열 수 없습니다. 네트워크에 연결할 수 없습니다' 라는 메시지가 표시되는 문제가 발생했습니다. 다른 브라우저에서는 문제가 없었지만, 유독 Safari에서만 이런 현상이 나타났습니다.

 

 

제가 개발하고 있던 서버 아키텍처는 다음과 같았습니다.

[클라이언트] ──HTTPS──> [Nginx] ──HTTP──> [Spring Boot]

클라이언트는 HTTPS로 서버에 접속을 시도 합니다. 서버 내부에서는 Nginx의 리버스 프록시를 사용해 Spring Boot 서버에 HTTP로 요청을 전달하고 있었죠.

 

 

그럼 왜 이런 문제가 발생했을까?

✅ 1.구조상 문제: 리버스 프록시 구조

  • 클라이언트는 HTTPS로 접속함
  • 하지만 Nginx는 내부에서 Spring Boot에 HTTP로 요청을 전달함
  • Spring Boot는 받은 요청만 보고 판단하기 때문에  "아 이거 HTTP 요청이네?"라고 착각하고 http://로 리디렉션 생성

✅ 2.Spring Boot의 오판

Spring Boot가 기본적으로 보는 정보는 HttpServletRequest.getSchme()인데, 이걸 Nginx가 넘기지 않으면 무조건 HTTP로 인식합니다.

즉, 

  • 클라이언트는 https://example.com/submit로 들어왔는데
  • Spring은 그냥 HTTP 요청이라고 착각해서
  • redirect:/result → http://example.com/result 리디렉션 했던 것이죠
// 문제 상황 코드 예시
@PostMapping("/submit")
public String submit() {
    // 로직 처리...
    return "redirect:/result";  // Spring Boot가 http://example.com/result로 리디렉션
}

✅ 3.Safari의 강력한 보안 정책

Safari는 보안 강등(downgrade)을 적극적으로 차단한다고 합니다.

"지금 HTTPS에서 왔는데, 너 왜 HTTP로 보내려고 해? 이거 위험한데??"
→ 해당 페이지를 열 수 없습니다 에러 발생

 

그럼 이제 어떻게 해결했는지 알아보겠습니다.

 

 

해결방법

✅ 1. Nginx 설정

location / {
    proxy_pass http://localhost:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;  # ✅ 이 설정이 핵심!
}
  • 클라이언트가 https://로 접속했는지 http://로 접속했는지를 $scheme 변수에 담고
  • 이걸 X-Forwarded-Proto라는 헤더로 Spring Boot에 전달함

 

✅ 2. Spring Boot 설정

# application.yml
server:
  forward-headers-strategy: framework
  • 이건 Spring Boot가 X-Forwarded-* 헤더를 신뢰하고 활용하겠다는 의미
  • HttpServletRequest.getScheme() 호출 시 → 이 값을 헤더로부터 파싱함
  • 그 결과: 리디렉션 시 https://가 유지됨

 

추가 설명: 그래서 X-Forwarded-Proto가 뭔데?

📌 정의:

클라이언트가 원래 사용한 프로토콜 (HTTP 또는 HTTPS)을 프록시 서버(Nginx 등)가 백엔드 서버에게 전달하기 위해 사용하는 HTTP 헤더.

즉, 사용자가 실제로 http://로 요청했는지, https://로 요청했는지를 백엔드가 알 수 있게 알려주는 신호 입니다.

🧩 구조 예시:

🔹 사용자가 https://myapp.com/login으로 요청

GET /login HTTP/1.1
Host: myapp.com

 

🔹 Nginx는 이걸 받고, 내부적으로 Spring Boot에게는 이렇게 보냄:

GET /login HTTP/1.1
Host: myapp.com
X-Forwarded-Proto: https
X-Real-IP: 1.2.3.4
X-Forwarded-For: 1.2.3.4

 

이때 X-Forwarded-Proto: https ← 이게 핵심입니다.

Spring Boot는 이걸 보고 "아~ 클라이언트는 HTTPS로 요청했구나!" 라고 알 수 있는거죠.

 

 

최종 결과

이 두 가지 설정을 적용한 결과, Safari에서도 정상적으로 HTTPS 리디렉션이 이루어졌으며 문제가 완전히 해결되었습니다.

저와 비슷한 문제를 겪는 분들은 위 설정을 따라 해보시길 바랍니다.

 

감사합니다.

'Error Log' 카테고리의 다른 글

[Swagger] 스웨거 오류: Unable to render this definitionThe provided definition does not specify a valid version field.  (0) 2024.12.03
[Querydsl] No sources given 에러  (0) 2024.12.01
'Error Log' 카테고리의 다른 글
  • [Swagger] 스웨거 오류: Unable to render this definitionThe provided definition does not specify a valid version field.
  • [Querydsl] No sources given 에러
Economy98
Economy98
공부하고 기록하기
  • Economy98
    Economy_Dev
    Economy98
  • 전체
    오늘
    어제
    • 분류 전체보기 (76) N
      • Spring Framework (12)
      • BOJ, Programmers (22)
      • Java (5) N
      • JDBC (6)
      • JPA (9)
      • Spring Transaction (3)
      • Algorithm (1)
      • Web (5)
      • Projects (2)
        • 쇼핑몰 프로젝트 (0)
        • 열람실 & 도서관 프로젝트 (2)
      • Network (2)
      • 나의 공부방 (5)
      • 끄적끄적 (1)
      • Error Log (3)
      • CS (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • Github
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    그리디 알고리즘
    propagation
    예외 처리
    백준
    java
    브루트포스 알고리즘
    스프링부트
    JPA
    jdbc
    자바
    restful api
    다이나믹 프로그래밍
    정렬
    자바 문제
    Spring
    스프링
    백준 풀이
    트랜잭션
    백준 자바 풀이
    자바 문제 풀이
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
Economy98
Spring Boot + Nginx 환경에서 redirect 시 HTTPS가 HTTP로 변경되는 문제 해결하기
상단으로

티스토리툴바