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

빅터 코스탄

Cookie Store API란 무엇인가요?

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

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

설명 읽기

현재 상태

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

비동기 쿠키 저장소를 사용하려면 어떻게 해야 하나요?

오리진 트라이얼 사용 설정

로컬에서 사용해 보려면 명령줄에서 API를 사용 설정하세요.

chrome --enable-blink-features=CookieStore

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

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

아마도 쿠키는 필요하지 않습니다.

새로운 API를 알아보기 전에, 쿠키는 여전히 웹 플랫폼의 최악의 클라이언트 측 저장소 기본 요소이며, 여전히 최후의 수단으로 사용해야 한다는 점을 알려드립니다. 이것은 우연이 아닙니다. 쿠키는 웹에서 최초의 클라이언트 측 저장 메커니즘이었고, 그 이후로 Google은 많은 것을 배웠습니다.

쿠키를 회피하는 주된 이유는 다음과 같습니다.

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

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

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

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

그렇더라도 쿠키를 사용해야 할 합당한 이유가 있기 때문에 이 문서를 계속 읽고 있는 것입니다.

오래된 document.cookie API는 애플리케이션의 버벅거림이 발생하는 원인이 상당히 보장됩니다. 예를 들어 document.cookie getter를 사용할 때마다 브라우저에서는 개발자가 요청한 쿠키 정보를 얻을 때까지 자바스크립트 실행을 중지해야 합니다. 이로 인해 프로세스 홉 또는 디스크 읽기가 필요할 수 있으며 UI에 버벅거림이 발생합니다.

이 문제를 간단하게 해결하려면 document.cookie getter에서 async 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에서 반환된 프로미스가 확인된 후에만 적용됩니다.

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

// undefined

설문조사를 하지 말고 관찰

자바스크립트에서 쿠키에 액세스하는 데 널리 사용되는 애플리케이션은 사용자의 로그아웃을 감지하고 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');
}

그러나 서비스 워커에서 쿠키 변경사항을 관찰하는 것은 조금 다릅니다. 서비스 워커의 절전 모드를 해제하는 데는 많은 비용이 들 수 있으므로 worker가 관심을 갖는 쿠키 변경사항을 명시적으로 설명해야 합니다.

아래 예에서는 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 깜빡임 구성요소에 신고해 주세요.

설명서에 설명된 것 이외의 성능 측정 및 사용 사례에 관해 자세히 알아보고자 합니다.

추가 리소스