로컬에서만 테스트하다가 서버에 처음으로 배포했을 때 한번 쯤은 겪어봤을 정책이슈인 CORS. 토이프로젝트를 만들어보면서 한번 겪어봤었기 때문에 저는 "CORS? 이제 그정도는 껌이지."라고 생각하며 쉽게 봤었던 것 같습니다.
그때 당시에는 로그인도 없는 간단한 프로젝트였기 때문에...
Kakao OAuth를 활용한 JWT 방식의 로그인을 구현하면서 쿠키를 사용하게 되었습니다. 분명 로컬에서는 잘 교환되던 쿠키가 AWS를 통해 각각 배포하고 테스트하니 백엔드에서 보내는 쿠키가 보이지 않았습니다.
프론트엔드의 경우, S3 버킷을 거쳐 CloudFront를 통해 배포되고 백엔드는 EC2에서 실행되는 서버가 AWS LoadBalancer를 거치기 때문에 처음에는 쿠키가 제대로 도착하지 않은 것이라고 생각했습니다.
하지만 HTTP 요청을 하나씩 뜯어보면서 백엔드에서 보낸 Set-Cookie 헤더는 제대로 포함되어 있음을 알 수 있었습니다.
위의 정보를 바탕으로 뻘짓도 많이 해보면서 여러 시행착오를 겪어본 결과, 프론트엔드와 백엔드에 CORS 설정을 해뒀어도 쿠키 또한 따로 설정이 필요했었습니다.
Cookie Domain
은 쿠키는 기본적으로 쿠키가 유효한 사이트를 명시하기 위해 쿠키에 도메인을 설정할 수 있습니다.
이렇게 도메인이 설정된 쿠키는 해당 도메인에서만 유효한 쿠키가 됩니다. 위에서 csrf_access_token 쿠키는 .moview.io를 대상으로 쿠키가 설정되었기 때문에, .moview.io를 대상으로 한 요청에만 csrf_access_token 쿠키가 전송됩니다.
SameSite 쿠키
는 크로스 사이트(Cross-site)로 전송하는 요청의 경우 쿠키의 전송에 제한을 두도록 합니다. SameSite 쿠키의 정책으로 None, Lax, Strict 세 가지 종류를 선택할 수 있고, 각각 동작하는 방식이 다릅니다. SameSite를 설명하기 위해서는 퍼스트 파티 쿠키와 서드 파티 쿠키에 대한 지식이 필요합니다.
퍼스트 파티 쿠키와 서드파티 쿠키?
쿠키는 기본적으로 쿠키가 유효한 사이트를 명시하기 위해 쿠키에 도메인을 설정할 수 있는데, 이 설정된 도메인을 기준으로 퍼스트 파티 쿠키(First-party cookies)와 서드 파티 쿠키(Third-party cookies)가 나뉘어 집니다.
여기서는 간단하게 설명하자면, 서드 파티 쿠키는 사용자가 접속한 페이지와 다른 도메인으로 전송하는 쿠키를 말합니다. 그리고 퍼스트 파티 쿠키는 반대로 이해하면 간단합니다. 퍼스트 파티 쿠키는 사용자가 접속한 페이지와 같은 도메인으로 전송되는 쿠키를 말합니다. 모두 쿠키가 가진 도메인을 기준으로 생각하시면 편합니다.
None
: SameSite 가 탄생하기 전 쿠키와 동작하는 방식이 같습니다. None으로 설정된 쿠키의 경우 크로스 사이트 요청의 경우에도 항상 전송됩니다. 즉, 서드 파티 쿠키도 전송됩니다. 따라서, 보안적으로도 SameSite 적용을 하지 않은 쿠키와 마찬가지로 문제가 있는 방식입니다. SameSite 속성으로 None을 사용하려면 반드시 해당 쿠키는 Secure 쿠키여야 합니다. Secure 쿠키는 HTTPS가 적용된(그러니까 암호화된) 요청에만 전송되는 쿠키입니다.Strict
: 가장 보수적인 정책입니다. Strict로 설정된 쿠키는 크로스 사이트 요청에는 항상 전송되지 않습니다. 서드 파티 쿠키는 전송되지 않고, 퍼스트 파티 쿠키만 전송됩니다.Lax
: Strict에 비해 상대적으로 느슨한 정책입니다. Lax로 설정된 경우, 대체로 서드 파티 쿠키는 전송되지 않지만, 몇 가지 예외적인 요청에는 전송됩니다.결국 저희 서비스의 경우에는 프론트엔드의 도메인이 moview.io
였고, 백엔드는 api.moview.io
였기 때문에 도메인명은 같지만 서브도메인이 달라서 정책위반으로 Set-Cookie가 헤더에 담겨서 보내졌지만 실제로 쿠키가 담기지는 않았던 것이었습니다.
이 문제를 해결하기 위해서는 일단
도메인이 반드시 같아야 합니다
. SameSite를 None으로 하고 HTTPS가 적용되어 있었기 때문에 Secure 옵션도 함께 줘서 쿠키를 보내봤지만 쿠키가 여전히 담기지 않았습니다. 최근에는 정책이 바뀌었는지 조사가 필요한 것 같아요.
저희는 다행스럽게도 도메인은 같았기 때문에 쿠키의 Domain을 .moview.io
로 설정하여 해결할 수 있었습니다.
예시로, example.com과 test.example.com이 쿠키를 교환하려면 쿠키의 도메인을 .example.com
으로 하면 됩니다. example.com과 exampleapi.com 같이 도메인이 다른 경우에는 불가능합니다.