Acesso assíncrono a cookies HTTP

Victor Costan

O que é a API Cookie Store?

A API Cookie Store expõe cookies HTTP aos service workers e oferece uma alternativa assíncrona a document.cookie. Com a API, é mais fácil:

  • Evite instabilidade na linha de execução principal acessando cookies de forma assíncrona.
  • Evite pesquisar cookies, já que é possível observar mudanças neles.
  • Acesse cookies de service workers.

Leia a explicação

Status atual

Step Status
1. Criar uma explicação Concluído
2. Criar rascunho inicial da especificação Concluído
**3. Receba feedback e itere nas especificações** **Em andamento**
4. Teste de origem Pausada
5. Iniciar Not started

Como faço para usar o armazenamento de cookies assíncrono?

Ativar o teste de origem

Para testá-la localmente, ative a API na linha de comando:

chrome --enable-blink-features=CookieStore

Transmitir essa sinalização na linha de comando ativa a API globalmente no Chrome para a sessão atual.

Como alternativa, ative a sinalização #enable-experimental-web-platform-features em chrome://flags.

Você (provavelmente) não precisa de cookies

Antes de mergulhar na nova API, gostaria de declarar que os cookies ainda são o pior primitivo de armazenamento do lado do cliente da plataforma da Web e ainda devem ser usados como último recurso. Isso não é um acidente. Os cookies foram o primeiro mecanismo de armazenamento do lado do cliente na Web e aprendemos muito desde então.

Os principais motivos para evitar cookies são:

  • Os cookies transferem seu esquema de armazenamento para a API de back-end. Cada solicitação HTTP carrega um instantâneo do cookie jar. Isso facilita a inclusão de dependências no formato de cookie atual para os engenheiros de back-end. Quando isso acontece, o front-end não pode alterar o esquema de armazenamento sem implantar uma alteração correspondente no back-end.

  • Os cookies têm um modelo de segurança complexo. Os recursos da Modern Web Platform seguem a mesma política de origem, o que significa que cada aplicativo recebe o próprio sandbox e é completamente independente de outros aplicativos que o usuário possa estar executando. Os escopos de cookie criam uma história de segurança significativamente mais complexa, e a simples tentativa de resumir isso dobraria o tamanho deste artigo.

  • Os cookies têm custos de alto desempenho. Os navegadores precisam incluir um snapshot dos seus cookies em todas as solicitações HTTP. Assim, toda alteração nos cookies precisa ser propagada nas pilhas de armazenamento e rede. Os navegadores modernos têm implementações de armazenamento de cookies altamente otimizadas, mas nunca será possível tornar os cookies tão eficientes quanto os outros mecanismos de armazenamento, que não precisam se comunicar com a pilha de rede.

Por todos os motivos acima, os aplicativos modernos da Web precisam evitar cookies e, em vez disso, armazenar um identificador de sessão no IndexedDB e adicionar explicitamente o identificador ao cabeçalho ou corpo de solicitações HTTP específicas usando a API fetch.

Dito isso, você ainda está lendo este artigo porque tem um bom motivo para usar cookies...

A tradicional API document.cookie é uma fonte bastante garantida de instabilidade para o aplicativo. Por exemplo, sempre que você usa o getter document.cookie, o navegador precisa interromper a execução do JavaScript até ter as informações de cookie solicitadas. Isso pode levar um salto de processo ou uma leitura de disco e causar instabilidade na interface.

Uma solução simples para esse problema é mudar do getter document.cookie para a API Cookie Store assíncrona.

await cookieStore.get('session_id');

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

O setter document.cookie pode ser substituído de maneira semelhante. Lembre-se de que a mudança só será aplicada depois que a promessa retornada por cookieStore.set for resolvida.

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

// undefined

Observar, não pesquisar

Um aplicativo conhecido usado para acessar cookies no JavaScript é detectar quando o usuário sai e atualizar a interface. Atualmente, isso é feito pesquisando document.cookie, que introduz instabilidade e tem um impacto negativo na duração da bateria.

A API Cookie Store oferece um método alternativo para observar mudanças nos cookies, o que não requer pesquisa.

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);
  }
});

Service Workers de boas-vindas

Devido ao design síncrono, a API document.cookie não foi disponibilizada para service workers. A API Cookie Store é assíncrona e, portanto, é permitida nos service workers.

A interação com os cookies funciona da mesma maneira em contextos de documentos e em service workers.

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

No entanto, observar mudanças nos cookies é um pouco diferente em service workers. Ativar um service worker pode ser muito caro, então temos que descrever explicitamente as mudanças de cookies em que o worker está interessado.

No exemplo abaixo, um aplicativo que usa o IndexedDB para armazenar dados do usuário em cache monitora as mudanças no cookie de sessão e descarta os dados em cache quando o usuário sai.

// 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;
    }
  }
});

Práticas recomendadas

Em breve.

Feedback

Se você testar essa API, conte o que achou. Envie feedback sobre o formato da API para o repositório de especificações e informe os bugs de implementação ao componente Blink>Storage>CookiesAPI Blink.

Queremos saber mais sobre medições de performance e casos de uso além daqueles descritos na explicação.

Outros recursos