개요
API 서버가 HTTPS 프로토콜로 변경됐으며 Secure 속성이 추가된 Cookie를 사용하기 위해
로컬에서도 HTTPS 개발 환경을 구성할 필요가 있다.
Vite 기반 프로젝트에서는 Proxy 기능을 활용해 프로토콜을 재지정하고,
CORS 회피를 위해 Cookie의 SameSite 설정을 함께 조정한다.
내용
#1. Proxy란
Proxy는 클라이언트와 서버 사이에서 요청을 대신 전달해 주는 대리 서버를 의미한다.
클라이언트가 직접 백엔드 서버에 접근하지 않고, 프론트 개발 서버(Vite)가 요청을 받아 대신 전달하는 방식이다.
일반적인 요청 흐름은 아래와 같다.
브라우저 > Vite dev server(프록시) > 백엔드 API 서버
┌──────────────┐ 요청 ┌────────────────────┐
│ Browser │ ─────────────────→ │ Vite Dev Server │
│ (localhost) │ │ (Proxy) │
└──────────────┘ └────────────────────┘
│
│ 백엔드로 전달
▼
┌──────────────────────────┐
│ Backend API Server │
│ (carhartt-usedtransactions.com)
└──────────────────────────┘
│
│ 응답
▼
┌──────────────┐ 응답 ┌────────────────────┐
│ Browser │ ←───────────────── │ Vite Dev Server │
└──────────────┘ └────────────────────┘
프록시를 통해서 얻을 수 있는 이점은 다음과 같다.
[ 1. CORS 회피 ]
로컬 개발 시 프론트와 백엔드의 주소/포트가 다르면 CORS 에러가 발생한다.
프록시를 사용하면 브라우저는 같은 Origin으로 인식하므로 CORS 문제를 우회할 수 있다.
[ 2. 보안 설정/쿠키 처리 테스트 ]
백엔드는 종종 특정 도메인에서만 쿠키를 허용한다.
프록시는 이 요청/응답을 원하는 대로 변환할 수 있기 때문에
Domain, SameSite, Secure 등의 쿠키 속성을 조정하면서 로그인/인증을 테스트할 수 있다.
[ 3. 개발 도메인 분리 ]
실제 서비스 도메인과 비슷한 개발 도메인을 구성하고 싶을 때 프록시를 활용할 수 있다.
개발 도메인: https://carhartt-local.com
운영 API: https://carhartt-usedtransactions.com
프록시를 사용하면 프론트 서버는 개발 도메인으로 동작하면서도
백엔드 요청은 운영 API 서버로 자연스럽게 전달된다.
[ 4. Mock/실제 API 전환에 유리 ]
프록시가 있으면 아래와 같이 처리할 수 있다.
- mock 데이터 사용할 때는 로컬에서 처리
- 실제 서버를 사용할 때는 프록시를 통해 전달
[ 5. 정리 ]
- 요청/응답을 중간에서 조작할 수 있는 중계 서버다.
- 개발 환경에서 CORS 우회가 주요 목적이다.
- Cookie Domain/SameSite/Secure 문제 해결에 유리하다.
- 개발/운영 주소 분리를 쉽게 구성할 수 있다.
- Vite는 프록시 설정이 간단하며 기본 제공한다.
#2. Vite에서 HTTPS 옵션을 환경변수 기반으로 활성화하기
HTTPS 프로토콜 사용을 위해서는 SSL 인증서가 필요하다.
아래 가이드를 참고해 인증서를 발급할 수 있다.
가이드 : Vite HTTPS 개발 환경용 OpenSSL 인증서 발급 가이드
우리 프로젝트에서는 .env.development에서 VITE_USE_HTTPS=true 여부로
HTTPS 적용을 전환하도록 구성했다.
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd());
const useHttps = env.VITE_USE_HTTPS === 'true';
return {
server: {
...(useHttps
? {
https: {
key: fs.readFileSync(
path.resolve(process.env.HOME, '.cert/localhost-key.pem')
),
cert: fs.readFileSync(
path.resolve(process.env.HOME, '.cert/localhost-cert.pem')
),
},
}
: {}),
host: 'carhartt-local.com',
}
};
});
[ 주요 특징 ]
VITE_USE_HTTPS값으로 HTTPS를 활성/비활성화 제어- 인증서 경로를 유저 홈(~/.cert/) 기준으로 고정해 재사용 증가
- 개발용 도메인을
carhartt-local.com으로 지정해 실제 운영 도메인과 유사한 환경을 구성
#3. HTTPS+Proxy 구성에서 쿠키 처리 문제 해결하기
HTTPS 기반 개발 환경을 구성하는 과정에서 가장 문제가 되었던 부분은 Cookie 속성 처리였다.
쿠키의 Domain, SameSite, Secure 속성을 정의해야 하는데
Vite proxy 사용 시 백엔드 서버가 내려주는 Set-Cookie 값을 적절히 변환하지 않으면
로그인이 제대로 되지 않는다.
[ 쿠키 변환이 필요한 이유 ]
- 백엔드가 내려주는 쿠키 Domain이
carhartt-usedtransactions.com이라 로컬에서는 저장되지 않는다. - SameSite 기본값이
Lax라 cross-site redirect 후 쿠키가 전달되지 않는다. - HTTPS가 아닌 경우 Secure 속성이 있으면 쿠키가 저장되지 않는다.
아래는 프로젝트에서 사용한 쿠키 재정의 로직이다.
configure: (proxy, options) => {
proxy.on('proxyRes', (proxyRes) => {
const cookies = proxyRes.headers['set-cookie'];
if (cookies) {
const newCookies = cookies.map((cookie) => {
let modified = cookie
.replace(/Domain=[^;]+/i, 'Domain=localhost')
.replace(/SameSite=[^;]+/i, 'SameSite=None');
if (!useHttps) {
modified = modified.replace(/; Secure/gi, '');
}
return modified;
});
proxyRes.headers['set-cookie'] = newCookies;
}
});
}
위 로직을 통해 개발 환경에서도 인증/로그인이 가능한 형태로 재정의할 수 있다.
#4. 실제 로컬 개발 HTTPS 흐름
┌───────────────┐
│ Browser │
│ https://carhartt-local.com
└───────────────┘
│
│ ① /v1/order 요청
▼
┌───────────────────────────┐
│ Vite Dev Server │
│ (Proxy + HTTPS 옵션) │
└───────────────────────────┘
│
│ ② proxy가 요청을 가로채 target으로 전달
▼
┌────────────────────────────────────┐
│ Backend API Server │
│ https://carhartt-usedtransactions.com
└────────────────────────────────────┘
│
│ ③ 백엔드가 Set-Cookie 헤더 포함하여 응답
▼
┌───────────────────────────┐
│ Vite Dev Server │
│ 쿠키 Domain/Secure 수정 │
│ Domain=localhost │
│ SameSite=None │
│ Secure 제거(필요 시) │
└───────────────────────────┘
│
│ ④ 수정된 쿠키를 브라우저로 전달
▼
┌───────────────┐
│ Browser │
│ 로그인 유지 │
└───────────────┘
마무리
로컬 HTTPS 환경을 구성하는 과정은 번거롭지만
결제 모듈이나 리다이렉트 기반 인증처럼 보안이 필요한 기능을 개발하려면 필수적이다.
인증서 생성 → 신뢰 설정 → 환경변수 기반 HTTPS 활성화 → proxy 쿠키 재정의 등 일련의 과정을 잘 갖추면
실제 운영 환경과 거의 동일한 형태로 개발을 진행할 수 있다.
'사이드 프로젝트 아카이빙' 카테고리의 다른 글
| [React Query] 응답 처리 ‐ API 함수 vs Callback(onSuccess onError) 역할 분리 (0) | 2025.11.23 |
|---|---|
| [HTTPS] Vite HTTPS 개발 환경용 OpenSSL 인증서 발급 가이드 (0) | 2025.11.23 |
| [배포] Cloudflare Pages 배포에 인증 추가하기 (0) | 2025.11.23 |
| [Image Upload]이미지 리사이징(Resizing) with pica lib (0) | 2025.11.23 |
| [키워드 알림] 통신 방식 비교 (Polling, SSE) (1) | 2025.11.23 |