오늘의 이슈는 cross-domain 환경에서 쿠키가 등록 되지 않는것에서 시작된 이슈였다.
로그인 버튼을 누르면 server domain에는 쿠키가 정상적으로 등록이 되지만 web domain에는 쿠키가 등록이 되지않아 유저정보를 받아올 수 없는 이슈였다.
먼저 환경에 대한 설명으로는 A라는 도메인을 가진 next.js로 만들어진 웹 페이지, B라는 도메인을가진 koa로 만들어진 서버가 존재하며 두 개의 project에서 oauth를 사용해야 할 일이 있어 kakao,google oauth를 연동하게 되었다.
이는 localhost에서는 정상적으로 동작하였지만(도메인이 같음) release시 cross-domain환경이 되어 쿠키가 정상적으로 등록되지 않는 이슈가 발생하였다.
왜 이런 이슈가 발생하게 되었는지에 대한 가장 큰 원인은 cors라고 말할 수 있다. 먼저 cross domain에 쿠키를 등록하기 위해서는 다음의 3가지 cors 규칙 + 1가지의 cookie옵션을 꼭 명시하여야한다.
- Access-Control-Allow-Credentials 부분이 true여야 할 것
- Access-Control-Allow-Origin 의 url이 (절대 도메인이 아님) 쿠키를 등록하고자 하는 사이트의 주소와 일치해야할것
- Method들이 허용되어 있을 것 -> 여기서 추가적으로 preflight 관련된 이슈가 생길수도 있을 것 같아서 OPTIONS까지 허용해주었다.
- 쿠키의 옵션의 sameSite부분이 'lax' 혹은 'none' 일 것
위의 cors + cookie option들을 정상적으로 셋팅하였다면 이론적으로 쿠키는 cross-domain 환경에서도 정상적으로 등록되어야 하는것이 맞다. 하지만 이번에는 정상적으로 등록되지 않는것이 문제였다.
여러가지 방면으로 시도를 해보며 12시간가까이 테스트 + 문서를 찾고 공부하며 koa의 cors라이브러리 버그는 아닌지 쿠키 옵션에 허점이 있는지 등등 거의 쿠키에 대한 모든것을 고려하며 생각하여 얻은 결과로는 이는 지극히 정상적인 동작이였다는것이다.
그리고 이 부분에서 문제에 대한 정의와 해결책에 대한 내용은 아래와 같다.
문제점
- front, server는 도메인이 다름 즉 이는 cross-domain이라고 말할 수 있음
- 쿠키는 cross-domain에서 전송하기 위해서는 sameSite 옵션이 “lax” 혹은 “none”의 값을 가져야함
- “lax”는 cross-domain간 쿠키 전송을 하게 해주나 link, href 등 유저의 navigation 관련 명령에만 전송을 함 따라서 useSWR의 getMethod로는 cross-domain 쿠키를 전송하지 못하고 이에따라 유저의 정보를 불러올 수 없기에 로그인이 안되는 이슈가 발생함
- 즉 이를 해결하기 위해서는 쿠키의 sameSite option은 “none”값을 가져야함
- sameSite option을 “none”으로 설정하기 위해서는 반드시 secure option이 “true”여야만 함(secure는 http위에서 true로 설정시 에러가 발생하므로 https위에서만 동작함)
- 하지만 현재 서버는 http위에서 동작하고있는 상태임
- 이를 해결하기 위해서는 https를 사용하여 secure옵션을 true, sameSite옵션을 “none”으로 설정하던가 같은 도메인을 사용하는 방안이 있음
해결방안
- proxy를 사용하기 (cross-domain 환경이 아닌것 처럼 동작할 수 있기에 위의 대부분의 문제점들이 해결됨)
- 서버에서 https 사용하기 (가장 어려울꺼같지만 가장 확실한 해결방법이라고 생각함)
- 같은 도메인 사용하기 (업계에서 많이 안쓰이는 방법일수도 있음 하지만 개인적으로는 우리 서버인데 왜 다른 도메인을 사용하지? 라는 의문이 들긴함)
여기서 나는 위의 해결 방안중 proxy를 사용하는것을 채택하였다.
가장 큰 이유로는 next.js에는 아주 훌륭한 proxy를 기본으로 제공해주기 때문이다 (참고: https://nextjs.org/docs/api-reference/next.config.js/rewrites)
여기서 proxy를 사용하여 cross-domain이 아닌 환경으로 만들어 개발을 진행하였으며 정상적으로 동작할 줄 알았으나 여기서 정상적으로 동작하지 않아 멘탈이 조금 깨졌었던 것 같다. 개발을 할 때 간과한것이 한 가지 있었던것이다.
그 문제에 대하여 정리한 것이 바로 아래의 내용이다.
next의 rewrite를 사용해서 proxy처럼 사용하면 잘 되지 않을까라는 생각을 했으나 현재 oauth의 구조는 provider -> kakao auth page -> callback인데 kakao auth page가 callback으로 redirect시키는거라 kakao auth page가 origin이기 때문에 callback부분에 proxy를 추가적으로 다는게 아닌이상 웹 페이지에는 그것만으로는 절대 쿠키를 등록할 수 없음
즉 proxy를 사용한다는 방안은 서버의 callback route부분의 앞에 웹 페이지의 도메인으로 변환시켜주는 프록시를 다는것이라고 생각하면 될 것 같음 (이 때 cors 관련해서 이슈가 다시 한 번 발생할 확률이 매우 높음)
그리고 문제가 명확하기에 이를 아주 쉽게 해결할 수 있는 방법을 찾아내었다. 그것은 바로 callback을 웹 페이지 도메인의 서버에 올린다음 해당 서버에서 다시 우리의 서버로 요청을 보내어 oauth 전용 proxy를 만드는 것이다.
그리고 이 방법은 next.js를 사용하기에 아주 쉽게 웹 페이지 도메인에 서버를 추가할 수 있었으며 이를 통해 cross-domain간 oauth 쿠키 등록에 성공하였으며 정상적으로 동작하는것을 확인할 수 있었다.
이번 이슈에서 나름대로 쿠키는 잘 알고 있다고 생각하다가도 정말 여러가지로 어려운 부분이 너무 많다고 생각하였으며 이러한 난이도에 비해 보안적으로 절대로 완벽하다고는 할 수 없는 store기에 사용하는데 있어 꼭! 잘 알고 사용하거나 주의 깊게 사용해야 할 것 같다고 생각하였다.
2022년 5월 7일에 작성된 글입니다.
'browser' 카테고리의 다른 글
브라우저 캐시 정책으로 인한 버전 충돌 에러 해결 (1) | 2024.03.31 |
---|---|
브라우저는 어떻게 캐시 만료시간을 정하나요? (1) | 2024.03.29 |