Cross-domain 환경에서 oauth를 통한 access-token 쿠키 등록하기

김종식·2022년 5월 7일
0
post-thumbnail

오늘의 이슈는 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옵션을 꼭 명시하여야한다.

  1. Access-Control-Allow-Credentials 부분이 true여야 할 것
  2. Access-Control-Allow-Origin 의 url이 (절대 도메인이 아님) 쿠키를 등록하고자 하는 사이트의 주소와 일치해야할것
  3. Method들이 허용되어 있을 것 -> 여기서 추가적으로 preflight 관련된 이슈가 생길수도 있을 것 같아서 OPTIONS까지 허용해주었다.
  4. 쿠키의 옵션의 sameSite부분이 'lax' 혹은 'none' 일 것

위의 cors + cookie option들을 정상적으로 셋팅하였다면 이론적으로 쿠키는 cross-domain 환경에서도 정상적으로 등록되어야 하는것이 맞다. 하지만 이번에는 정상적으로 등록되지 않는것이 문제였다.

여러가지 방면으로 시도를 해보며 12시간가까이 테스트 + 문서를 찾고 공부하며 koa의 cors라이브러리 버그는 아닌지 쿠키 옵션에 허점이 있는지 등등 거의 쿠키에 대한 모든것을 고려하며 생각하여 얻은 결과로는 이는 지극히 정상적인 동작이였다는것이다.

그리고 이 부분에서 문제에 대한 정의와 해결책에 대한 내용은 아래와 같다.

문제점

  1. front, server는 도메인이 다름 즉 이는 cross-domain이라고 말할 수 있음

    2.쿠키는 cross-domain에서 전송하기 위해서는 sameSite 옵션이 “lax” 혹은 “none”의 값을 가져야함

  2. “lax”는 cross-domain간 쿠키 전송을 하게 해주나 link, href 등 유저의 navigation 관련 명령에만 전송을 함 따라서 useSWR의 getMethod로는 cross-domain 쿠키를 전송하지 못하고 이에따라 유저의 정보를 불러올 수 없기에 로그인이 안되는 이슈가 발생함

  3. 즉 이를 해결하기 위해서는 쿠키의 sameSite option은 “none”값을 가져야함

  4. sameSite option을 “none”으로 설정하기 위해서는 반드시 secure option이 “true”여야만 함(secure는 http위에서 true로 설정시 에러가 발생하므로 https위에서만 동작함)

  5. 하지만 현재 서버는 http위에서 동작하고있는 상태임

  6. 이를 해결하기 위해서는 https를 사용하여 secure옵션을 true, sameSite옵션을 “none”으로 설정하던가 같은 도메인을 사용하는 방안이 있음

해결방안

  1. proxy를 사용하기 (cross-domain 환경이 아닌것 처럼 동작할 수 있기에 위의 대부분의 문제점들이 해결됨)

  2. 서버에서 https 사용하기 (가장 어려울꺼같지만 가장 확실한 해결방법이라고 생각함)

  3. 같은 도메인 사용하기 (업계에서 많이 안쓰이는 방법일수도 있음 하지만 개인적으로는 우리 서버인데 왜 다른 도메인을 사용하지? 라는 의문이 들긴함)

여기서 나는 위의 해결 방안중 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기에 사용하는데 있어 꼭! 잘 알고 사용하거나 주의 깊게 사용해야 할 것 같다고 생각하였다.

profile
웹개발자 / 잘못된 정보에 대한 피드백은 언제나 환영입니다. ^^

0개의 댓글