HTTP 쿠키에 대한 비동기 액세스

Victor Costan

Cookie Store API란 무엇인가요?

Cookie Store API는 HTTP 쿠키를 서비스 워커에 노출하고 document.cookie의 비동기 대안을 제공합니다. 이 API를 사용하면 다음 작업을 더 쉽게 수행할 수 있습니다.

  • 쿠키에 비동기식으로 액세스하여 기본 스레드의 버벅거림을 방지합니다.
  • 쿠키 변경사항을 관찰할 수 있으므로 쿠키를 폴링하지 마세요.
  • 서비스 워커에서 쿠키에 액세스합니다.

설명 자료 읽기

현재 상태

단계 상태
1. 설명 만들기 완전함
2. 사양의 초기 초안 만들기 완전함
**3. 의견 수집 및 사양 반복** **진행 중**
4. 오리진 트라이얼 일시중지됨
5. 출시 시작되지 않음

비동기 쿠키 저장소는 어떻게 사용하나요?

출처 무료 체험 사용 설정

로컬에서 사용해 보려면 명령줄에서 API를 사용 설정하면 됩니다.

chrome --enable-blink-features=CookieStore

명령줄에서 이 플래그를 전달하면 Chrome에서 현재 세션에 대해 전 세계적으로 API가 사용 설정됩니다.

또는 chrome://flags에서 #enable-experimental-web-platform-features 플래그를 사용 설정할 수 있습니다.

쿠키가 필요하지 않은 경우

새 API를 살펴보기 전에 쿠키는 여전히 웹 플랫폼에서 가장 나쁜 클라이언트 측 저장소 원시이며 최후의 수단으로 사용해야 한다고 말씀드리고자 합니다. 이는 우연이 아닙니다. 쿠키는 웹의 첫 번째 클라이언트 측 저장소 메커니즘이었으며 그 이후로 많은 것을 배웠습니다.

쿠키를 사용하지 않는 주된 이유는 다음과 같습니다.

  • 쿠키는 스토리지 스키마를 백엔드 API로 가져옵니다. 각 HTTP 요청은 쿠키 저장소의 스냅샷을 전송합니다. 이를 통해 백엔드 엔지니어가 현재 쿠키 형식에 종속 항목을 쉽게 도입할 수 있습니다. 이렇게 되면 프런트엔드는 백엔드에 일치하는 변경사항을 배포하지 않고는 스토리지 스키마를 변경할 수 없습니다.

  • 쿠키에는 복잡한 보안 모델이 있습니다. 최신 웹 플랫폼 기능은 동일한 출처 정책을 따릅니다. 즉, 각 애플리케이션은 자체 샌드박스를 가져오며 사용자가 실행 중일 수 있는 다른 애플리케이션과 완전히 독립적입니다. 쿠키 범위는 훨씬 더 복잡한 보안 스토리를 만들어내며, 이를 요약하려고만 해도 이 도움말의 크기가 두 배가 됩니다.

  • 쿠키는 성능 비용이 높습니다. 브라우저는 모든 HTTP 요청에 쿠키의 스냅샷을 포함해야 하므로 쿠키의 모든 변경사항이 저장소 및 네트워크 스택에 전파되어야 합니다. 최신 브라우저에는 쿠키 저장소 구현이 최적화되어 있지만, 네트워크 스택과 통신할 필요가 없는 다른 저장소 메커니즘만큼 쿠키를 효율적으로 만들 수는 없습니다.

위의 모든 이유로 인해 최신 웹 애플리케이션은 쿠키를 사용하지 않고 대신 세션 식별자를 IndexedDB에 저장하고 fetch API를 통해 특정 HTTP 요청의 헤더 또는 본문에 식별자를 명시적으로 추가해야 합니다.

하지만 쿠키를 사용해야 할 합당한 이유가 있기 때문에 이 도움말을 계속 읽고 있습니다.

오래된 document.cookie API는 애플리케이션에서 상당히 확실한 버벅거림 소스입니다. 예를 들어 document.cookie getter를 사용할 때마다 브라우저는 요청한 쿠키 정보를 가져올 때까지 JavaScript 실행을 중지해야 합니다. 이로 인해 프로세스 호프 또는 디스크 읽기가 발생할 수 있으며 UI가 버벅거립니다.

이 문제를 간단하게 해결하는 방법은 document.cookie getter를 비동기 Cookie Store API로 전환하는 것입니다.

await cookieStore.get('session_id');

// {
//   domain: "example.com",
//   expires: 1593745721000,
//   name: "session_id",
//   path: "/",
//   sameSite: "unrestricted",
//   secure: true,
//   value: "yxlgco2xtqb.ly25tv3tkb8"
// }

document.cookie setter도 비슷한 방식으로 대체할 수 있습니다. 변경사항은 cookieStore.set에서 반환된 Promise가 해결된 후에만 적용된다는 점에 유의하세요.

await cookieStore.set({name: 'opt_out', value: '1'});

// undefined

관찰하고 설문조사하지 않음

JavaScript에서 쿠키에 액세스하는 데 사용되는 인기 있는 애플리케이션은 사용자가 로그아웃할 때 이를 감지하고 UI를 업데이트하는 것입니다. 현재는 document.cookie를 폴링하여 이를 수행하며, 이로 인해 버벅거림이 발생하고 배터리 수명에 부정적인 영향을 미칩니다.

Cookie Store API는 폴링이 필요하지 않은 쿠키 변경사항을 관찰하는 대체 방법을 제공합니다.

cookieStore.addEventListener('change', event => {
  for (const cookie of event.changed) {
    if (cookie.name === 'session_id') sessionCookieChanged(cookie.value);
  }
  for (const cookie of event.deleted) {
    if (cookie.name === 'session_id') sessionCookieChanged(null);
  }
});

서비스 워커 환영

동기 설계로 인해 document.cookie API는 서비스 워커에서 사용할 수 없습니다. Cookie Store API는 비동기식이므로 서비스 워커에서 허용됩니다.

쿠키와 상호작용하는 것은 문서 컨텍스트와 서비스 워커에서 동일한 방식으로 작동합니다.

// Works in documents and service workers.
async function logOut() {
  await cookieStore.delete('session_id');
}

하지만 서비스 워커에서는 쿠키 변경사항을 관찰하는 방법이 약간 다릅니다. 서비스 워커를 깨우는 것은 상당히 비용이 많이 들 수 있으므로 워커가 관심을 갖는 쿠키 변경사항을 명시적으로 설명해야 합니다.

아래 예에서 IndexedDB를 사용하여 사용자 데이터를 캐시하는 애플리케이션은 세션 쿠키의 변경사항을 모니터링하고 사용자가 로그아웃하면 캐시된 데이터를 삭제합니다.

// Specify the cookie changes we're interested in during the install event.
self.addEventListener('install', event => {
  event.waitUntil(cookieStore.subscribeToChanges([{name: 'session_id'}]));
});

// Delete cached data when the user logs out.
self.addEventListener('cookiechange', event => {
  for (const cookie of event.deleted) {
    if (cookie.name === 'session_id') {
      indexedDB.deleteDatabase('user_cache');
      break;
    }
  }
});

권장사항

앞으로 출시될 예정이며,

의견

이 API를 사용해 보고 의견을 알려주세요. API 형태에 관한 의견은 사양 저장소에 전달하고, 구현 버그는 Blink>Storage>CookiesAPI Blink 구성요소에 신고하세요.

특히 설명에 설명된 것 이외의 실적 측정 및 사용 사례에 관심이 있습니다.

추가 리소스