본문 바로가기
Python

[Python] FastAPI 에서 HTTPS 설정하기

by teamnova 2025. 6. 12.
728x90

안녕하세요.

오늘은 FastAP에서 HTTPS 설정을 해보겠습니다.

 

1. HTTPS

HTTPS(HyperText Transfer Protocol Secure)는 HTTP 프로토콜에 SSL/TLS 암호화 계층을 추가한 보안 통신 프로토콜입니다.

즉, 웹 브라우저와 서버 사이의 모든 데이터가 암호화되어 전송됩니다.

HTTP vs HTTPS

  • HTTP: 평문(암호화되지 않은) 데이터 전송
  • HTTPS: 암호화된 데이터 전송 (SSL/TLS 사용)

SSL/TLS

SSL(Secure Sockets Layer)와 TLS(Transport Layer Security)는 인터넷에서 데이터를 암호화해 안전하게 전송하기 위한 표준 프로토콜입니다.

SSL은 원래 넷스케이프에서 개발된 보안 프로토콜이고, 이후 더 강력하고 안전한 TLS로 발전했습니다.

현재는 TLS가 표준이며, "SSL"이라는 용어는 관습적으로 함께 사용됩니다.

SL/TLS는 대칭키 암호화 공개키 암호화를 결합해 데이터의 기밀성, 무결성, 인증성을 제공합니다.

 

SSL/TLS가 제공하는 보안 기능

  1. 기밀성(Confidentiality)
    데이터를 암호화하여 중간에 노출되어도 내용을 알 수 없게 만듭니다.
  2. 무결성(Integrity)
    데이터가 전송 중에 변조되었는지 확인할 수 있습니다.
  3. 인증(Authentication)
    서버(또는 클라이언트)가 신뢰할 수 있는 주체임을 증명합니다.

SSL/TLS의 동작 원리(핸드셰이크)

  1. 클라이언트가 서버에 접속하면서 인증서(공개키)를 요청
  2. 서버가 인증서를 전달, 클라이언트는 신뢰할 수 있는 인증서인지 검증
  3. 클라이언트가 대칭키(세션키)를 생성해 서버의 공개키로 암호화해 전송
  4. 서버는 개인키로 복호화해 대칭키를 획득
  5. 이후 데이터 통신은 이 대칭키로 암호화되어 빠르고 안전하게 이루어짐

왜 HTTPS를 사용해야 하는가?

  • 개인정보/로그인 정보/결제 정보 등 민감한 데이터 보호
  • 중간자 공격(Man-In-The-Middle Attack) 방지
  • 브라우저 및 API 클라이언트의 신뢰 확보 (HTTP 사이트는 경고 메시지 발생)
  • OAuth2, JWT 등 인증 시스템의 보안성 확보
  • SEO(검색엔진 최적화) 측면에서도 HTTPS 사이트가 우선시됨

실제 서비스 배포 환경에서는 반드시 HTTPS를 적용해야 합니다.

 

2. FastAPI에서 HTTPS 적용 방법

2.1. 로컬 테스트용(개발용) Self-Signed 인증서 만들기

실제 서비스에서는 Let's Encrypt 등에서 무료로 발급받은 인증서를 사용하지만, 개발 환경에서는 임시(Self-Signed) 인증서로 테스트할 수 있습니다.

1) OpenSSL로 인증서 생성

터미널에서 아래 명령어를 실행하세요.

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout key.pem -out cert.pem \
  -subj "/C=KR/ST=Seoul/L=Seoul/O=Dev/OU=Dev/CN=localhost"
  • key.pem: 비공개키(Private Key)
  • cert.pem: 인증서(Certificate)

2) FastAPI(Uvicorn) 실행 시 SSL 옵션 추가

uvicorn main:app --reload --host 0.0.0.0 --port 8000 \
  --ssl-keyfile=key.pem --ssl-certfile=cert.pem
  • 이제 https://localhost:8000 으로 접속하면 HTTPS로 동작합니다.
  • 브라우저에서 "신뢰할 수 없는 인증서" 경고가 뜨는 것은 정상(개발용이기 때문).

2.2. 실서비스(운영 환경)에서 HTTPS 적용

1) 인증서 발급

  • Let's Encrypt: 무료, 자동 갱신 지원 (https://letsencrypt.org/)
  • 또는 유료 인증서(Comodo, GlobalSign 등)

2) 직접 Uvicorn에 적용 (권장 X)

운영 환경에서는 FastAPI(Uvicorn) 자체에 직접 인증서를 적용하기보다는
Nginx, Apache 등 프록시 서버를 앞단에 두고 HTTPS를 처리하는 것이 일반적입니다.

  • Nginx가 HTTPS를 처리하고, 내부적으로 FastAPI 서버(HTTP)로 프록시

3) Nginx 예시 설정

  • FastAPI(Uvicorn)는 HTTP(예: 127.0.0.1:8000)로만 실행하면 됨
  • 외부에서는 오직 Nginx(HTTPS)만 노출
server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate     /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        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;
    }
}

 

  • 인증서 파일(비공개키)은 절대 외부에 노출되면 안 됩니다.
  • 운영 환경에서는 반드시 정식 인증서를 사용해야 하며, 자동 갱신(Let's Encrypt의 certbot 등)도 필수적으로 관리해야 합니다.
  • API 서버와 클라이언트(브라우저, 앱 등) 모두 HTTPS를 강제 적용하도록 설정하세요.
  • 인증/인가 토큰(JWT 등)은 반드시 HTTPS 환경에서만 주고받아야 합니다.