HttpOnly 쿠키를 개발 서버에 설정하는 방법

먼저 개발 서버는 localhost 로 구동된다.

백엔드 API 서버는 도메인을 가지고 있기 때문에 브라우저의 동일 출처 정책에 어긋나게 된다. (SOP)

따라서 요청 자체를 거부당한다.

SOP 를 해결하기 위해 두가지 설정이 필요한데.

API 함수의 Base URL 을 상대경로로 변경하여 localhost 로 요청을 보내게 한다.

export const login = () => {
	http.post(`/api/session/v1/login`, null, {
		baseURL: process.env.REACT_APP_ENV === 'development' ? '' : 'https://api.backend.com',
	});
}

그 다음 Webpack 과 같은 개발 서버에서 Proxy 옵션을 설정한다.

devServer: {
	proxy: {
		'/api/login': {
			target: 'https://api.example.com',
			changeOrigin: true
		}
	}
}

/api/login 로 향하는 네트워크를 Webpack Proxy 가 가로채어 Target 으로 Origin 을 변경해 프록시가 대신 보내도록 한다.

프록시가 브라우저 대신 보내니까 SOP 를 우회하게 된다.

그런데 이렇게만 설정하면 HttpOnly 쿠키로 설정되지 않는다.

HttpOnly 쿠키는 보통 Refresh Token 과 같은 안전한 값에 사용한다.

HttpOnly 쿠키에 저장하면 클라이언트 측에 저장되지만 수정하지 못한다. JavaScript 로 쿠키를 탈취하는 등의 XSS 공격으로부터 보호된다. (document.cookie 로 접근하지 못한다.)

HttpOnly 쿠키를 설정하는 내용은 Chrome Network 탭에서 확인해볼 수 있다.

Response Header 
	set-cookie: 
		session=NDI2M2UwYmUtYjNjYS00Njk1LTk4NzgtMjllZjA1MTA5Mjcz; 
		Max-Age=86400; 
		Expires=Tue, 11 Nov 2025 13:58:29 GMT; 
		Domain=.example.co.kr; 
		Path=/; 
		Secure; 
		HttpOnly; 
		SameSite=Lax

도메인이 .example.co.kr 이기 때문에 쿠키는 localhost 에 저장되지 않는다.

개발 서버의 Proxy 부분을 좀 더 수정해야한다.

devServer: {
	proxy: {
		'/api/login': {
			target: 'https://api.example.com',
			changeOrigin: true
			cookieDomainRewrite: 'localhost'
		}
	}
}

cookieDomainRewrite 로 쿠키 도메인을 localhost 로 변경해야 개발 서버에 쿠키가 설정되어 인증된다.

추가로 쿠키를 전송하려면 BaseAPI 클라이언트는 withCredentials: true 옵션을 포함해야한다. (브라우저의 기본값은 쿠키를 보내지 않는 동작이다.)