주뇽's 저장소

리액트에서 HTTPS 설정을 받고 스프링으로 HTTP 요청을 유지하는 방법: Nginx를 이용한 SSL 종료 구현 🔒 본문

웹개발

리액트에서 HTTPS 설정을 받고 스프링으로 HTTP 요청을 유지하는 방법: Nginx를 이용한 SSL 종료 구현 🔒

뎁쭌 2024. 9. 10. 15:23
728x90
반응형

리액트에서 HTTPS 설정을 받고 스프링으로 HTTP 요청을 유지하는 방법: Nginx를 이용한 SSL 종료 구현 🔒

개발을 하다 보면 프론트엔드는 HTTPS를 사용하고 싶지만, 백엔드 서버는 HTTP를 그대로 유지해야 하는 상황이 있다. 이런 경우 Nginx를 이용한 SSL 종료(SSL Termination)를 구현하면 효과적으로 문제를 해결할 수 있다. 이 글에서는 리액트 애플리케이션과 스프링 부트 백엔드 사이에 Nginx를 두어 SSL 종료를 구현하는 방법에 대해 설명한다.

문제점: HTTPS와 HTTP 혼용의 어려움 😓

보안을 위해 프론트엔드에서는 HTTPS를 사용해야 하지만, 백엔드 서버는 여러 이유로 HTTP를 사용해야 하는 경우가 있다. 이런 상황에서 발생하는 주요 문제점은 다음과 같다:

  1. 혼합 콘텐츠(Mixed Content) 오류: HTTPS 페이지에서 HTTP 리소스를 로드하려고 하면 브라우저에서 보안 경고가 발생한다.
  2. 보안 취약점: 클라이언트와 서버 간의 전체 통신이 암호화되지 않아 중간자 공격에 취약할 수 있다.
  3. 설정의 복잡성: 프론트엔드와 백엔드에서 서로 다른 프로토콜을 사용하면 설정이 복잡해질 수 있다.

해결책: Nginx를 이용한 SSL 종료 구현 🛡️

이러한 문제를 해결하기 위해 Nginx를 이용한 SSL 종료를 구현할 수 있다. SSL 종료란 HTTPS 연결을 종료하고 내부적으로 HTTP를 사용하는 방식이다. 이 방법의 주요 이점은 다음과 같다:

  1. 보안 강화: 외부 통신은 모두 HTTPS로 암호화된다.
  2. 백엔드 부하 감소: SSL/TLS 처리를 Nginx가 담당하여 백엔드 서버의 부하를 줄인다.
  3. 유연한 구성: 프론트엔드와 백엔드 사이의 프로토콜 차이를 Nginx가 중재한다.

구현 단계:

1. Nginx 설정하기 🔧

Nginx 설정 파일(/etc/nginx/sites-available/default)을 다음과 같이 수정한다:

server {
    listen 80;
    server_name your_domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name your_domain.com;

    ssl_certificate /path/to/your/fullchain.pem;
    ssl_certificate_key /path/to/your/privkey.pem;

    location / {
        root /path/to/your/react/build;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        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;
    }
}

2. 스프링 부트 설정 수정하기 ⚙️

application.properties 또는 application.yml 파일에 다음 설정을 추가한다:

server:
  forward-headers-strategy: NATIVE

3. 리액트 애플리케이션 수정하기 🖥️

API 요청 시 상대 경로를 사용하도록 리액트 코드를 수정한다. 이는 매우 중요한 단계로, 모든 API 요청을 상대 경로로 변경해야 한다:

// 변경 전
fetch('http://your_domain.com/api/some-endpoint')

// 변경 후
fetch('/api/some-endpoint')
  .then(response => response.json())
  .then(data => console.log(data));

이렇게 상대 경로로 변경함으로써, 리액트 애플리케이션은 현재 호스트의 프로토콜(HTTPS)을 자동으로 사용하게 된다.

4. SSL 인증서 발급 및 설정 🔐

Let's Encrypt를 이용해 무료 SSL 인증서를 발급받고 Nginx에 설정한다:

sudo certbot --nginx -d your_domain.com

5. Nginx 재시작 🔄

설정을 적용하기 위해 Nginx를 재시작한다:

sudo systemctl restart nginx

SSE(Server-Sent Events) 지원을 위한 추가 설정: Nginx에서 실시간 통신 구현하기 🚀

개발을 하다 보면 실시간 데이터 전송이 필요한 상황이 자주 발생한다. 특히 HTTPS 환경에서 Server-Sent Events(SSE)를 사용하려면 추가적인 Nginx 설정이 필요하다. 이 글에서는 Nginx에서 SSE를 지원하기 위한 설정 방법을 상세히 설명한다.

문제점: 기본 HTTPS 설정으로는 SSE가 동작하지 않는다 😓

HTTPS 환경에서 기본 Nginx 설정만으로는 SSE가 제대로 동작하지 않는다. 주요 문제점은 다음과 같다:

  1. 연결이 중간에 끊어진다.
  2. 실시간 데이터 전송이 지연된다.
  3. 장기 연결이 유지되지 않는다.

이러한 문제들로 인해 채팅, 알림, 실시간 업데이트 등의 기능이 제대로 작동하지 않을 수 있다.

해결책: Nginx 설정 최적화하기 🛠️

이러한 문제를 해결하기 위해 Nginx 설정을 최적화해야 한다. 구체적인 설정 방법은 다음과 같다:

  1. Nginx 설정 파일 열기:

    sudo nano /etc/nginx/sites-available/default
  2. /api/ 위치 블록에 다음 설정 추가하기:

    location /api/ {
        proxy_pass http://43.201.129.54:8080;
        # 기존 설정...
    
        # SSE 지원을 위한 추가 설정
        proxy_set_header Connection '';
        chunked_transfer_encoding off;
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 3600s;
    }
  3. 설정 저장 및 Nginx 재시작:

    sudo nginx -t
    sudo systemctl restart nginx

각 설정의 의미 🧐

  1. proxy_set_header Connection '';: HTTP/1.1의 연결 유지(keep-alive) 기능을 비활성화한다. SSE는 장기 연결을 사용하므로 이 설정이 필요하다.

  2. chunked_transfer_encoding off: 청크 전송 인코딩을 비활성화한다. SSE는 연속적인 데이터 스트림을 사용하므로 이 설정이 필요하다.

  3. proxy_buffering off: Nginx의 버퍼링을 비활성화하여 실시간 데이터 전송을 가능하게 한다.

  4. proxy_cache off: 캐싱을 비활성화하여 항상 최신 데이터가 전송되도록 한다.

  5. proxy_read_timeout 3600s: 연결 타임아웃을 1시간으로 설정한다. SSE 연결은 장시간 유지될 수 있으므로 긴 타임아웃이 필요하다.

결론: 안정적인 실시간 통신 구현 🏆

이러한 설정을 통해 HTTPS 환경에서도 SSE를 안정적으로 사용할 수 있다. 실시간 기능이 필요한 웹 애플리케이션에서 이 방법을 활용하면 효과적인 실시간 통신을 구현할 수 있다. 특히 채팅 애플리케이션, 실시간 알림 시스템, 라이브 데이터 피드 등을 개발할 때 유용하게 사용할 수 있다.

Nginx 설정을 최적화함으로써 개발자는 더 나은 사용자 경험을 제공하는 웹 애플리케이션을 만들 수 있다. SSE를 활용한 실시간 통신은 웹 애플리케이션의 반응성과 사용자 참여도를 크게 향상시킬 수 있는 강력한 도구이다. 🌟