프로젝트/크루트

https와 cross domain으로 서버와 통신 시 쿠키 보내는 법

발전생 2022. 3. 24. 09:40

현재 서버와의 통신 사항은 이렇다

  • 프론트엔드와 백엔드가 서로 다른 도메인을 가지고 있다. (cross domain) = 서로 다른 url
  • 프론트엔드와 백엔드 모두 ssl을 끼고 통신한다. (https)

로컬에서 테스트할 때는 서버가 보내준 쿠키를 프론트 단에서 잘 저장했었다. 

프론트엔드 서버는 localhost:3000, 백엔드 서버는 localhost:8080에서 호스팅되고 있었다.

프론트엔드가 server side rendering 중이다.

 

문제는 서버와 프론트를 모두 호스팅하고 https로 통신할 때였다.

login을 해도 세션 쿠키가 브라우저에 저장되지 않아(혹은 쿠키는 받았지만 서버에 보내지 않아) 로그인이 정상적으로 성공하지 않았다.

이 글을 작성하고 보니 쿠키를 서버로 보내지 않았던 거다.

 

브라우저에서의 쿠키 기본 정책을 알아볼 필요가 있었다.

 

SameSite

서버에서 쿠키에 대해 아무 설정도 안 해주고 있었다. 그렇기 때문에 쿠키의 SameSite 속성 역시 undefined였다. undefined가 어떤 영향을 미치는지 알아봤다.

 

Lax
Cookies are not sent on normal cross-site subrequests (for example to load images or frames into a third party site), but are sent when a user is navigating to the origin site (i.e., when following a link).
This is the default cookie value if SameSite has not been explicitly specified in recent browser versions (see the "SameSite: Defaults to Lax" feature in the Browser Compatibility).

요즘 브라우저는 SameSite를 명시하지 않으면 Lax 값으로 해석한다. Lax는 다른 도메인으로 쿠키를 보내지 않는다. 

 

None
Cookies will be sent in all contexts, i.e. in responses to both first-party and cross-origin requests. If SameSite=None is set, the cookie Secure attribute must also be set (or the cookie will be blocked).

SameSite에 None을 설정하면 쿠키는 모든 상황에서 보낼 수 있다. 단, csrf 공격을 막기 위해 Lax가 기본 설정인 것이기 때문에 보안을 위해 secure 또한 쿠키에 추가해줘야 한다. secure를 설정하지 않으면 안전하지 않은 쿠키라 생각하고 차단한다. 

 

Secure

A Secure cookie is only sent to the server with an encrypted request over the HTTPS protocol. Note that insecure sites (http:) can't set cookies with the Secure directive.

쿠키에 Secure 속성이 있으면 https 통신일 때만 서버로 쿠키를 보낼 수 있다. 

 

 

 

그렇다면 이제 spring boot의 응답에 set-cookie 값을 설정해줘야 한다.

기존에 jsessionid를 보내는 게 있으니 거기에 추가적으로 sameSite와 secure만 추가해주면 된다.

 

bean 주입으로 설정할 수도 있지만 최신 스프링부트는 편하게 application.yml에서 설정해줄 수 있다.

로컬에서는 https를 안 쓰니 prod 버전에서만 아래 설정을 추가해줬다.

# cookie
server:
  servlet:
    session:
      cookie:
        same-site: none
        secure: true

 

postman에 https로 로그인 요청을 해보면 서버에서 Set-cookie에 secure, samesite=None 모두 설정된 것을 볼 수 있다.

초반에 HttpOnly 때문에 https가 쿠키를 못 받는 건 아닐까 생각도 했었지만 HttpOnly는 전혀 상관이 없다.

 

HttpOnly는 자바스크립트로 해당 쿠키를 조작할 수 없게 하는 속성이다. 

 

 

쿠키 값 확인

아래 사이트에 cookie의 속성들에 대해 잘 설명돼있다. 추가적으로 읽어보면 도움이 될 것이다.

인용 사이트:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

 

SameSite cookies - HTTP | MDN

The SameSite attribute of the Set-Cookie HTTP response header allows you to declare if your cookie should be restricted to a first-party or same-site context.

developer.mozilla.org