쿠키는 서버에서 생성을 요청해서 브라우저에 저장되는 값이다.
구글 사이트에 접속하는 것을 예시로 어떻게 동작하는지 확인해보자!
참고로 개발자 도구(F12) > Network 탭에 들어가면 브라우저와 서버가 요청을 주고 받는 과정을 확인할 수 있다.
[Response Header]
브라우저의 요청(www.goolge.com에 접속)에 서버가 응답을 할 때, 응답 헤더에 Set-Cookie 값을 넣어 전달한다. 이 값을 브라우저는 쿠키 값으로 저장한다.
Set-Cookie: {name}={value}; expires={date}; path=/; secure
Set-Cookie는 보통 다음과 같은 형식으로 전달되는 데, 쿠키 이름과 값 그리고 유효 기간 등을 지정할 수 있다.
[Request Header]
이후 요청에서는 현재 브라우저에 저장되어 있는 모든 쿠키를 Request Header에 Cookie라는 이름으로 서버에 전달한다. 첫 번째 이미지는 쿠키 값을 지우고 나서 처음 요청했을 때, 두 번째 이미지는 쿠키 값을 지우지 않고 한번 더 요청했을 때의 모습이다. 두 번째 요청했을 때는 이전 요청의 Set-Cookie로 쿠키 값이 추가되어, 더 많은 내용이 가는 것을 확인 할 수 있다.
서버에서 생성한 쿠키가 브라우저에서 제대로 저장되지 않아 개발자 도구를 확인해보니, Set-Cookie 속성에 ! 아이콘이 생겼고 마우스 오버하니 아래 메시지가 나왔다.
This attempt to set a cookie via a Set-Cookie header was blocked because it has ”Secure" attribute but was not received over a secure connection.
해석해보면 Cookie에 Secure 속성 추가 시 Secure Connection(https로 접속)을 하지 않으면 쿠키 세팅을 막는다는 내용이다. localhost로 접근했을 때는 문제가 안되었던 것으로 보아 아마 예외 처리가 되어 있는 것 같고, 개발 서버에서는 https 통신 처리가 안되어 있었기 때문에 http로 접근하여 문제가 생겼던 것이다.
MDN의 Set-Cookie 문서에 더 자세한 내용이 적혀있었다.
Secure
Indicates that the cookie is sent to the server only when a request is made with the
https:
scheme (except on localhost), and therefore, is more resistant to man-in-the-middle attacks.Note: Do not assume that
Secure
prevents all access to sensitive information in cookies (session keys, login details, etc.). Cookies with this attribute can still be read/modified either with access to the client's hard disk or from JavaScript if theHttpOnly
cookie attribute is not set.Insecure sites (
http:
) cannot set cookies with theSecure
attribute (since Chrome 52 and Firefox 52). For Firefox, thehttps:
requirements are ignored when theSecure
attribute is set by localhost (since Firefox 75).
Secure 속성이 붙은 쿠키는 https(localhost) 요청에서만 사용할 수 있고, Secure cookie라도 민감한 정보에 대한 모든 접근을 막을 수는 없다는 내용이었다.
private static final String active = System.getProperty("spring.profiles.active");
...
Cookie cookie = new Cookie(name, value);
// active profile에 따라 쿠키 보안 처리
if (active != null && (active.equals("prd") || active.equals("stg"))) {
cookie.setSecure(true);
}
그래서 active profile에 따라서 secure 속성으로 추가하거나 없애는 방향으로 코드를 수정했다. 개발 서버에 https 통신이 가능하도록 설정하는 방법도 있지만 서버마다 작업을 해줘야 하고, 보통 내부에서만 접근 가능하기 때문에 보안 연결이 꼭 필요할 것 같진 않아 이렇게 수정하는 것이 더 간단한 방법인 것 같다.