현재 서버와의 통신 사항은 이렇다
- 프론트엔드와 백엔드가 서로 다른 도메인을 가지고 있다. (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
'프로젝트 > 크루트' 카테고리의 다른 글
Entity에 @Transactional을 쓰고 싶은데 그래도 될까? (0) | 2022.03.28 |
---|---|
모바일 브라우저에서는 로그인이 안 되는 이유 (0) | 2022.03.25 |
테스트 케이스를 private으로 작성하면 test를 못 읽어요 (0) | 2022.03.20 |
vscode에서 template을 사용해서 귀찮음을 줄이자 (0) | 2022.03.18 |
JPA를 쓰는데 Fk 제약조건 때문에 골머리 썩고 있다면 cascade를 사용해서 쉽게쉽게 갑시다 (0) | 2022.03.10 |