WEGO ) 프론트의 개발환경에서 현재 배포된 백엔드 서버의 쿠키 공유가 불가능한 이슈
▪︎ 백엔드 서버와의 쿠키 공유
▫︎ 개발 환경에서 Set-Cookie로 받은 쿠키가 사라진다?
우리 프로젝트에서는 로그인을 하면 서버에서 Set-Cookie
를 통해 인증 토큰을 심어주고, 이후 인증이 필요한 요청 (로그인이 필요한 요청) 시 서버에서 프론트 요청의 쿠키를 읽어 인증 여부를 검증하고 그에 따른 응답을 반환하도록 설계되어있다.
배포 환경에서는 해당 로직이 잘 동작하였으나 개발 환경에서 받아온 쿠키가 계속해서 사라지는 현상이 일어났다.
▫︎ 문제 찾아보기
1️⃣ cors 설정이 제대로 안되어있는 것은 아닐까?
우선 백엔드 측에 cors
설정이 되어있는지를 확인해보았다. 백엔드 측에서는 개발환경과 배포환경에 대해 조건부로 잘 설정해주었다고 답변받았다. 혹시 실수가 있었던 것은 아닐까? next.js 의 rewrites
기능을 이용하여 프록시를 통해 cors
를 우회하여 테스트를 해보았다.
1 | // next.config.ts |
$ 여전히 쿠키는 사라진다. cors
문제는 아니다.
2️⃣ SameSite 를 None 으로 설정하면 해결되지 않을까? ( + Secure )
크로스 사이트 요청 시 쿠키 전송을 허가하는 설정인 SameSite=None
을 쿠키에 설정해주면 어떨까? 우선 SameSite
를 설정하기 위해서는 Secure 설정또한 추가로 해줘야 한다.
$ 해당 설정을 해주어도 동일한 현상이 일어났다.
3️⃣ HTTP 의 문제
문제 해결을 위해 쿠키의 각 속성에 대한 정보를 찾아보았다. Secure
설정을 위해서는 반드시 HTTPS
요청이 필요하다. HTTP
와 HTTPS
간의 scheme 차이 때문에 발생하는 문제였다는 것을 찾아냈다.
정리해보자면 SameSite=None
을 사용하기 위해서는 반드시 Secure
플래그가 필요하고, 이를 위해서는 다시 HTTPS
가 필요하다.
mkcert
로 로컬 인증서를 생성하고 pakage.json
의 script에서 “dev” 명령어에 —experimental-https
옵션을 사용하여 https://localhost:3000 에서 요청을 보내보았다.
1 | // package.json |
$ https 설정을 하여 SameSite=None, Secure 설정을 해줘도 쿠키는 사라졌다.
4️⃣ 크로스 도메인 문제인 것 같다. 쿠키를 구워줄 때, 개발환경에서의 요청이라면 Domain 값을
**localhost로 설정하면 되지 않을까?**
마지막으로 살펴볼만한 문제는 쿠키의 Domain
속성이다. 쿠키의 도메인은 .we-go.world 로 되어있다. 배포 주소가 we-go.world 이기 때문에 배포 사이트에서는 정상적으로 동작하고, localhost
인 개발환경에서는 정상적으로 동작하지 않는 것이 아닐까?
백엔드와 상황을 공유하니 백엔드에서 요청한 클라이언트의 Origin
을 읽어 그에 따라 조건부로 Domain
을 설정해주기로 했다.
1 |
|
그러나 동일하게 쿠키의 Domain
부분에는 .we-go.world 가 설정되어있다.
5️⃣ 서버는 자신의 도메인이 아닌 다른 도메인에 쿠키를 설정할 수 없다.
api 요청 시 백엔드도 localhost
에서 실행되었을 때에는 쿠키가 정상적으로 설정되었겠지만, 우리는 지금 배포된 백엔드에 테스트를 하려고 했다. 그래서 Domain
이 우리가 의도한 대로 설정되지 않았다.
6️⃣ 로컬 호스트 환경에서도 도메인 일치를 위해 Custom Domain을 설정하자.
프론트의 로컬 호스트 환경에서 Custom Domain
을 설정하여 프론트와 백엔드가 동일한 베이스 도메인 하에서 테스트할 수 있다면 해결되지 않을까?
/etc/hosts 파일을 수정하여 localhost
도메인을 front.we-go.world로 설정하고, 추가로 개발 모드 실행에서 도메인을 명시해주었다.
1 | // package.json |
▪︎ 정리
프론트와 백엔드 간의 쿠키 공유를 위해서는 서로의 베이스 도메인을 일치시켜야한다. 또한 서로가 동일한 도메인이 아닌 경우, 쿠키의 SameSite=None
과 Secure
설정이 필요하며 이를 위해서는 프론트의 개발 환경에서 HTTPS
를 사용해야만 한다.