cookie는 도메인이 같아야 주고 받을 수 있습니다.

우회할 방법은 cookie를 사용 안 하는 것 말고 없습니다.

에러로그: 쿠키 미전송 에러

문제: 클라이언트에서 cookie가 서버로 보내지지 않습니다.

클라이언트 서버 미들웨어에 2가지 token을 받아야 합니다. 하나는 access token을 header로 전달해줘야 합니다. 다른 하나는 cookie를 보내야 합니다. 서버에 post 요청을 하면 set-cookie 응답을 받는 것까지는 성공했습니다.

문제가 되는 지점은 받은 cookie를 다시 서버로 보낼 때입니다.

const accessToken = request.headers.get('Authorization');
const refreshToken = await cookies.get('user');

console.log('tokens', accessToken, refreshToken); // tokens Bearer (token 값) undefined

access token은 정상 전달을 확인할 수 있었습니다.

시도

thunder client 시도

thunder client에서 요청과 응답을 시험했습니다. 그것도 배포서버 기준으로 요청과 응답을 얻은 결과 문제가 없었습니다.

{
  "documents": [
    {
      "_id": "646f1ddb471560ac7eab3735",
      "question": "도큐사우르스 짱짱맨",
      "answer": "킹정",
      "submitDate": "Wed May 17 2023 21:11:26 GMT+0900 (한국 표준시)",
      "stackCount": "0",
      "userId": "646f05c55706b3d59520426b"
    },
    {
      "_id": "646f2c7b471560ac7eae6c9b",
      "question": "블로그를 더 간지나게 만드는 방법",
      "answer": "github pages로 DIY로 만든다.",
      "submitDate": "Wed May 17 2023 21:11:26 GMT+0900 (한국 표준시)",
      "stackCount": "0",
      "userId": "646f05c55706b3d59520426b"
    },
    {
      "_id": "646f36c14df1ac0e273eb0d8",
      "question": "혹시나 했는데???",
      "answer": "역시나!!!",
      "submitDate": "Wed May 17 2023 21:11:26 GMT+0900 (한국 표준시)",
      "stackCount": "1",
      "userId": "646f05c55706b3d59520426b"
    }
  ]
}

요청 응답이 정상적으로 동작했습니다.

여기서 추론해볼 수 있는 점은 브라우저 정책문제라는 것으로 에러의 면적을 줄일 수 있습니다. 브라우저가 차단하지만 thunder client는 차단을 하지 않아서 정상 동작했습니다.

배포전략이 틀렸습니다.

서브 도메인이나 다른 도메인에서 쿠키에 접속할 방법은 없습니다. site.com에서 생성한 쿠키를 other.com에선 절대 전송받을 수 없습니다.1

모던 자바스크립트 튜토리얼에서 찾은 내용입니다.

여기서 문제는 배포 도메인과 서버 도메인이 달라서 cookie를 공유할 수 없다는 것을 알 수 있습니다.

일단 무식한 전략으로 deno deploy의 도메인을 변경할 수 있는지 확인해봤습니다.

flash-card-frontend-pi.vercel.app을 도메인 설정으로 입력했습니다. 어림도 없습니다. 반대로 vercel에서 설정을 시도했는데 역시 이미 있어서 막혔다고 합니다.

문제가 있고 문제를 해결하기 위해서는 우회해야 합니다. 우회를 효과적으로 하는 방법을 ChatGPT에게 질문했습니다.

만약에 클라이언트와 서버가 통신하는데 클라이언트 도메인과 서버 도메인이 달라서 클라이언트가 쿠키를 전달할 수 없는 상황에서는 어떻게 대응할 수 있는가? 최대한 다양한 전략들을 알려주십시오.

- 저의 질문

즉 처음 설계할 때 다양한 도메인을 갖게 만들어서 문제가 된 것입니다. 또 개발부채가 추가되었다는 생각이 듭니다. 그냥 Next.js 사용했으면 같은 도메인 API 서버에 요청하고 응답받고 풀스택 프레임워크로 만들 수 있었을 텐데 아쉽습니다. 아마 2.0에서는 메타 프레임워크로 전환해야 합니다.

클라이언트와 서버가 서로 다른 도메인을 가지고 있을 때, 일반적인 방법으로는 클라이언트가 쿠키를 서버에 전달할 수 없습니다. 그러나 다음과 같은 다양한 전략들을 사용하여 이러한 상황에 대응할 수 있습니다:

  1. 도메인 간 통신 (Cross-Origin Communication):

웹 브라우저는 도메인 간 통신을 위한 다양한 메커니즘을 제공합니다. 가장 일반적인 방법은 Cross-Origin Resource Sharing (CORS)입니다. 서버에서 CORS 헤더를 설정하여 특정 도메인에서의 요청을 허용할 수 있습니다. 또는 서버에서 JSONP(JSON with Padding)이나 프록시를 사용하여 클라이언트와 서버 간의 통신을 중개할 수 있습니다.

  1. 서버 간 쿠키 전달 (Server-to-Server Cookie Transfer):

클라이언트와 서버 간의 쿠키 전달을 우회하기 위해 서버 간에 쿠키를 전달할 수 있는 메커니즘을 구현할 수 있습니다. 예를 들어, 클라이언트가 서버 A에 요청을 보내면, 서버 A는 서버 B에 요청을 전달하고, 서버 B에서는 클라이언트에 대한 응답과 함께 쿠키를 설정하여 서버 A로 전달할 수 있습니다.

  1. URL 매개변수 사용:

클라이언트가 서버에 쿠키를 전달할 수 없는 경우, URL 매개변수를 사용하여 필요한 정보를 직접 전달할 수 있습니다. 클라이언트는 매 요청마다 인증 정보나 세션 ID와 같은 데이터를 URL에 포함시켜 서버로 전달합니다. 서버는 해당 매개변수를 검사하여 클라이언트를 식별하고 필요한 동작을 수행합니다.

  1. 토큰 기반 인증 (Token-based Authentication):

클라이언트와 서버 간의 인증을 위해 토큰 기반 인증을 사용할 수 있습니다. 클라이언트는 로그인 시에 서버로부터 토큰을 받아서 보관하고, 각 요청마다 토큰을 헤더나 매개변수로 전달합니다. 서버는 토큰을 검증하여 클라이언트를 인증하고 요청을 처리합니다.

  1. 다른 도메인 간의 프레임 사용 (Cross-Domain Iframes):

클라이언트와 서버 간의 통신을 위해 다른 도메인 간에 프레임을 사용할 수 있습니다. 클라이언트에서 프레임을 로드하고, 프레임은 자체 도메인의 쿠키를 전달할 수 있습니다. 프레임은 부모 도메인과 통신하여 필요한 정보를 전달하고 응답을 받을 수 있습니다.

이러한 전략들은 서로 다른 도메인 간의 상호작용을 위해 사용되는 일반적인 메커니즘입니다. 선택할 전략은 상황에 따라 다를 수 있으며, 보안 요구사항과 기술적 제약 등을 고려하여 적합한 전략을 선택해야 합니다.

- ChatGPT

가장 단순하게 생각되는 전략은 Refresh token은 Session Storage에 저장하고 header에 같이 보내는 방법입니다. 그리고 나중에 배포를 수정하는 전략이 있습니다. 백엔드 코드를 또 건드리고 patch 릴리즈를 또 해야 하지만 최후의 전략으로 적당해 보입니다.

해결: cookie에서 session storage

axios interceptors와 refresh token을 활용한 jwt 토큰 관리 - HyunGyu-Kim

위 아티클에서 보면 cookie를 활용하고 있지 않습니다. 위 아티클에서도 백엔드에 도메인이 프론트엔드 도메인과 다를 것이라고 파악할 수 있습니다.

학습: cookie를 고통스러운 방식으로 배웠습니다.

원티드 특강

Atomic Design by Brad Frost

Thinking in React - react.dev

제어 컴포넌트 비제어 컴포넌트

테스트

개발환경 설정

yarn create vite
yarn add storybook
yarn add @vanilla-extract/css

dry-frontend / dry-design-system

Q&A


https://goshacmd.com/controlled-vs-uncontrolled-inputs-react/

https://wix.github.io/Detox/

https://github.com/ynawhocodes/self-perish-project

Footnotes

  1. 쿠키와 document.cookie - 모던자바스크립트 튜토리얼