본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

Tools

로컬 개발 환경에 HTTPS 적용하기

추가
목차6개 항목
출처와 참고

sejin 님의 글 「로컬 개발환경에 HTTPS 적용하기」(2023.06)을 바탕으로, 프레임워크 설정은 각 공식 문서로 확인해 재구성한 노트다.

로컬에서도 HTTPS가 필요한 경우

브라우저는 localhost와 *.localhost를 신뢰할 수 있는 출처로 본다. 그래서 Service Worker, Web Authentication 같은 보안 컨텍스트 API는 로컬에서는 HTTP로도 돌아간다. 그래도 다음 경우엔 로컬 HTTPS가 필요하다.

상황이유
Mixed Content 디버깅운영과 같은 조건(HTTPS 페이지)을 재현해야 한다
Secure 쿠키HTTPS 연결에서만 전송된다
HTTP/2 이상브라우저는 HTTPS에서만 HTTP/2를 쓴다
HTTPS를 요구하는 라이브러리·API외부 SDK, OAuth 콜백 등
커스텀 호스트 이름 (example.dev)localhost가 아니면 보안 컨텍스트 예외를 받지 못한다

왜 mkcert인가

방법문제
공인 CA 인증서localhost나 예약 도메인에는 발급되지 않는다
자체 서명(self-signed) 인증서브라우저가 경고를 띄우고 일부 기능이 막힌다
mkcert로컬 루트 CA를 만들어 내 기기·브라우저 신뢰 목록에 넣고, 그 CA로 인증서를 서명한다 → 경고 없음

Let's Encrypt도 로컬 개발에는 이 방식을 권한다.

설치와 인증서 발급

# macOS (nss는 Firefox를 쓸 때만)
brew install mkcert
brew install nss
 
# Windows (Chocolatey 또는 Scoop)
choco install mkcert
scoop bucket add extras && scoop install mkcert
 
# Linux: 인증서 도구(libnss3-tools 등)를 먼저 설치하고 릴리스 바이너리를 받는다
mkcert -install        # 로컬 루트 CA 생성 + 시스템·브라우저 신뢰 목록에 등록
mkcert -CAROOT         # rootCA.pem 위치 (모바일 기기에 설치할 때)
mkcert "*.example.dev" localhost 127.0.0.1 ::1   # 인증서 발급 (와일드카드 가능)
# → 현재 폴더에 인증서(.pem)와 개인키(-key.pem) 파일이 생긴다

루트 CA 파일(rootCA-key.pem)은 절대 공유하지 않는다. 누군가 손에 넣으면 그 기기의 통신을 가로챌 수 있는 인증서를 마음대로 만들 수 있다. 팀원은 각자 mkcert -install을 실행한다.

서버에 붙이기

대상방법
ApacheSSLEngine on, SSLCertificateFile, SSLCertificateKeyFile
Nginxlisten 443 ssl;, ssl_certificate, ssl_certificate_key
Node.jshttps.createServer({ key, cert }, handler)
http-serverhttp-server -S -C cert.pem -K key.pem
Next.jsnext dev --experimental-https (아래)
Nuxt 3devServer.https에 key·cert 경로
// Node.js
const https = require('https');
const fs = require('fs');
 
https
  .createServer(
    { key: fs.readFileSync('./example.dev-key.pem'), cert: fs.readFileSync('./example.dev.pem') },
    (req, res) => { /* ... */ },
  )
  .listen(3000);

프레임워크 개발 서버

Next.js는 개발 서버에 HTTPS 옵션이 있다. --experimental-https만 주면 내부적으로 mkcert를 써서 로컬에서 신뢰되는 인증서를 만들어 붙이고, 직접 만든 인증서를 넘길 수도 있다.

next dev --experimental-https
next dev --experimental-https \
  --experimental-https-key ./example.dev-key.pem \
  --experimental-https-cert ./example.dev.pem
  • Vite는 server.https에 key·cert를 넘기거나 @vitejs/plugin-basic-ssl을 쓴다.
  • 개발 서버가 HTTPS를 지원하지 않으면 앞에 HTTPS 리버스 프록시(local-ssl-proxy, Caddy 등)를 둔다. HMR은 WebSocket으로 동작하므로 프록시가 WebSocket 업그레이드를 지원해야 한다.
  • Nuxt(Vite)에서 HMR 연결이 끊기면 vite.server.hmr에 protocol: 'wss'와 host를 지정한다.
  • Next.js 커스텀 서버(createServer)로 HTTPS를 붙이는 방법은 자동 최적화를 잃으므로 쓰지 않는다.

정리

  • localhost는 대부분 보안 컨텍스트라 HTTP로 충분하지만, Secure 쿠키·HTTP/2·커스텀 호스트가 필요하면 로컬 HTTPS를 쓴다.
  • mkcert = 로컬 루트 CA 생성 + 신뢰 등록 + 인증서 발급. 경고 없는 인증서를 명령 세 줄로 얻는다.
  • 루트 CA 개인키는 공유 금지. 팀원마다 따로 설치한다.
  • 프레임워크 개발 서버는 내장 HTTPS 옵션을 먼저 쓰고, 없으면 프록시를 앞에 두되 WebSocket(HMR) 지원을 확인한다.

관련 노트: HTTPS와 TLS, 쿠키와 세션, Next.js

원본 기록1

댓글

GitHub 계정으로 댓글을 남길 수 있어요.