Acesso assíncrono a cookies HTTP

Victor Costan

O que é a API Cookie Store?

A API Cookie Store expõe cookies HTTP a service workers e oferece uma alternativa assíncrona para document.cookie. A API facilita o seguinte:

  • Evite instabilidade na linha de execução principal acessando cookies de forma assíncrona.
  • Evite a pesquisa de cookies, porque as mudanças neles podem ser observadas.
  • Acesse cookies de service workers.

Leia o texto explicativo

Status atual

Etapa Status
1. Criar uma explicação Concluído
2. Criar um rascunho inicial da especificação Concluído
**3. Coletar feedback e iterar a especificação** **Em andamento**
4. Teste de origem Pausada
5. Lançamento Não iniciado

Como usar a loja de cookies assíncrona?

Ativar o teste de origem

Para testar localmente, a API pode ser ativada na linha de comando:

chrome --enable-blink-features=CookieStore

A transmissão dessa flag na linha de comando ativa a API globalmente no Chrome para a sessão atual.

Como alternativa, ative a flag #enable-experimental-web-platform-features em chrome://flags.

Você provavelmente não precisa de cookies

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

Os principais motivos para evitar cookies são:

  • Os cookies trazem o esquema de armazenamento para a API de back-end. Cada solicitação HTTP carrega um resumo do cookie jar. Isso facilita para engenheiros de back-end introduzirem dependências no formato de cookie atual. Depois disso, o front-end não poderá mudar o esquema de armazenamento sem implantar uma mudança correspondente no back-end.

  • Os cookies têm um modelo de segurança complexo. Os recursos da plataforma Web moderna seguem a mesma política de origem, o que significa que cada aplicativo tem seu próprio sandbox e é completamente independente de outros aplicativos que o usuário possa estar executando. Os escopos de cookies são uma história de segurança muito mais complexa, e apenas tentar resumir isso dobraria o tamanho deste artigo.

  • Os cookies têm custos de desempenho altos. Os navegadores precisam incluir um instantâneo dos cookies em cada solicitação HTTP. Portanto, todas as alterações nos cookies precisam ser propagdas nas pilhas de armazenamento e de 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 da Web modernos devem 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 API document.cookie é uma fonte de lentidão bastante garantida para seu 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 do cookie solicitadas. Isso pode exigir um salto de processo ou uma leitura de disco e causar instabilidade na interface.

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

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. Tenha em mente 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 para acessar cookies do JavaScript é detectar quando o usuário sai e atualizar a interface. Isso é feito atualmente por meio de pesquisa 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 de cookies, 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 em workers de serviço.

A interação com os cookies funciona da mesma forma 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 as mudanças de cookies é um pouco diferente nos service workers. Acordar um service worker pode ser muito caro. Por isso, precisamos descrever explicitamente as mudanças de cookie 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 armazenados 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, nos diga o que achou. Envie feedback sobre a forma da API ao repositório de especificações e informe bugs de implementação ao componente Blink>Storage>CookiesAPI Blink.

Temos interesse especial em saber mais sobre as medições de desempenho e os casos de uso além dos descritos na explicação.

Outros recursos