Teste de origem para suporte a cabeçalho HTTP no acesso ao Storage

Natalia Markoborodova
Natalia Markoborodova

O Chrome está iniciando um teste de origem para adicionar cabeçalhos HTTP à API Storage Access (SAA) na versão 130: Cabeçalhos de acesso ao armazenamento. O novo cabeçalho de solicitação Sec-Fetch-Storage-Access e o cabeçalho de resposta Activate-Storage-Access têm como objetivo oferecer suporte a recursos que não são de iframe e melhorar o desempenho e a experiência do usuário em sites que dependem de conteúdo incorporado, como widgets de mídias sociais, calendários e ferramentas interativas.

Fluxo do JavaScript (e suas limitações)

Antes, o SAA exigia uma chamada de API JavaScript para document.requestStorageAccess() em cada recarga, mesmo que o usuário já tivesse concedido a permissão. Embora eficaz, esse método apresenta limitações:

  • Várias viagens de ida e volta pela rede:o processo geralmente envolve várias solicitações de rede e recargas de página antes que o conteúdo incorporado funcione totalmente.
  • Dependência de iframe:a execução do JavaScript exigia o uso de iframes ou subrecursos dentro de iframes, o que limitava a flexibilidade dos desenvolvedores.

Por exemplo, um widget de calendário do calendar.example incorporado no website.example usando apenas JavaScript ficaria assim:

  1. Carregar um marcador de posição:website.example solicita o widget. Como o widget calendar.example incorporado em website.example não tem acesso aos cookies não particionados, um widget de marcador de posição é renderizado.
  2. Solicitar permissão:o marcador de posição é carregado e, em seguida, chama document.requestStorageAccess() para solicitar a permissão storage-access.
  3. O usuário escolhe conceder a permissão.
  4. Recarregar o widget:o widget é atualizado, desta vez com acesso ao cookie, e, por fim, carrega o conteúdo personalizado.
  5. Sempre que o usuário acessa um site que incorpora o widget calendar.example novamente, o fluxo é exatamente igual ao das etapas 1, 2 e 4. A única simplificação é que o usuário não precisa conceder o acesso novamente.

Esse fluxo é ineficiente: se o usuário já tiver concedido a permissão de armazenamento, o carregamento inicial do iframe, a chamada document.requestStorageAccess() e a recarga subsequente se tornam desnecessários e criam latência.

O novo fluxo com cabeçalhos HTTP

Os novos cabeçalhos de acesso ao armazenamento permitem o carregamento mais eficiente de conteúdo incorporado, incluindo recursos que não são de iframe.

Com os cabeçalhos de acesso ao armazenamento, o navegador vai buscar recursos automaticamente com o cabeçalho de solicitação Sec-Fetch-Storage-Access: inactive definido se o usuário já tiver concedido a permissão. Nenhuma ação do desenvolvedor é necessária para definir o cabeçalho da solicitação. O servidor pode responder com o cabeçalho Activate-Storage-Access: retry; allowed-origin="<origin>", e o navegador vai tentar novamente a solicitação com as credenciais necessárias.

Cabeçalho de solicitação

Sec-Fetch-Storage-Access: <access-status>

Quando um usuário visita uma página que incorpora conteúdo entre sites, o navegador inclui automaticamente o cabeçalho Sec-Fetch-Storage-Access em solicitações entre sites que podem exigir credenciais (como cookies). Esse cabeçalho indica o status da permissão de acesso ao cookie da incorporação. Confira como interpretar os valores:

  • none: a incorporação não tem a permissão storage-access e, portanto, não tem acesso a cookies não particionados.
  • inactive: a incorporação tem a permissão storage-access, mas não a usa. A incorporação não tem acesso a cookies não particionados.
  • active: a incorporação tem acesso não particionado ao cookie. Esse valor será incluído em todas as solicitações entre origens que tiverem acesso a cookies não particionados.

Cabeçalhos de resposta

Activate-Storage-Access: <retry-or-reload>

O cabeçalho Activate-Storage-Access instrui o navegador a tentar novamente a solicitação com cookies ou carregar o recurso diretamente com o SAA ativado. O cabeçalho pode ter os seguintes valores:

  • load: instrui o navegador a conceder ao incorporador acesso a cookies não particionados do recurso solicitado.
  • retry: o servidor responde que o navegador precisa ativar a permissão de acesso ao armazenamento e, em seguida, tentar novamente a solicitação.
Activate-Storage-Access: retry; allowed-origin="https://site.example"
Activate-Storage-Access: retry; allowed-origin=*
Activate-Storage-Access: load

Suporte a recursos que não são iframes

A atualização dos cabeçalhos de acesso ao armazenamento ativa o SAA para conteúdo incorporado que não é iframe, como imagens hospedadas em um domínio diferente. Anteriormente, nenhuma API da plataforma da Web permitia o carregamento desses recursos com credenciais em navegadores se os cookies de terceiros não estivessem disponíveis. Por exemplo, o embedding-site.example pode solicitar uma imagem:

   <img src="https://server.example/image"/>

O servidor pode responder com conteúdo ou um erro, dependendo se um cookie está disponível:

app.get('/image', (req, res) => {
  const headers = req.headers;
  const cookieHeader = headers.cookie;
  // Check if the embed has the necessary cookie access
  if (!cookieHeader || !cookieHeader.includes('foo')) {
  // If the cookie is not present, check if the browser supports Storage Access headers
    if (
      'sec-fetch-storage-access' in headers &&
      headers['sec-fetch-storage-access'] == 'inactive'
    ) {
    // If the browser supports Storage Access API, retry the request with storage access enabled
      res.setHeader('Activate-Storage-Access', 'retry; allowed-origin="https://embedding-site.example"');
    }
    res.status(401).send('No cookie!');
   } else {
    // If the cookie is available, check if the user is authorized to access the image
    if (!check_authorization(cookieHeader)) {
      return res.status(401).send('Unauthorized!');
    }
    // If the user is authorized, respond with the image file
    res.sendFile("path/to/image.jpeg");
  }
});

Se o cookie não estiver disponível, o servidor vai verificar o valor do cabeçalho de solicitação Sec-Fetch-Storage-Access. Se esse valor for definido como inactive, o servidor vai responder com o cabeçalho Activate-Storage-Access: retry, indicando que a solicitação precisa ser repetida com acesso ao armazenamento. Se não houver um cookie e o cabeçalho Sec-Fetch-Storage-Access não tiver o valor inativo, a imagem não será carregada.

Fluxo do cabeçalho HTTP

Com os cabeçalhos HTTP, o navegador pode reconhecer quando o usuário já concedeu a permissão de acesso ao armazenamento ao widget e carregar o iframe com acesso a cookies não particionados durante visitas subsequentes.

Com os cabeçalhos de acesso ao armazenamento, as visitas às páginas seguintes vão acionar o seguinte fluxo:

  1. O usuário visita website.example, que tem o calendar.example incorporado novamente. Essa busca ainda não tem acesso ao cookie, como antes. No entanto, o usuário já concedeu a permissão storage-access, e a busca inclui um cabeçalho Sec-Fetch-Storage-Access: inactive para indicar que o acesso a cookies não particionados está disponível, mas não em uso.
  2. O servidor calendar.example responde com um cabeçalho Activate-Storage-Access: retry; allowed-origin="<origin>" (neste caso, <origin> seria https://website.example) para indicar que a busca de recursos exige o uso de cookies não particionados com a permissão de acesso ao armazenamento.
  3. O navegador tenta novamente a solicitação, desta vez incluindo cookies não particionados (ativando a permissão storage-access para essa busca).
  4. O servidor calendar.example responde com o conteúdo personalizado do iframe. A resposta inclui um cabeçalho Activate-Storage-Access: load para indicar que o navegador precisa carregar o conteúdo com a permissão storage-access ativada, ou seja, carregar com acesso não particionado ao cookie, como se document.requestStorageAccess() tivesse sido chamado.
  5. O user agent carrega o conteúdo do iframe com acesso a cookies não particionados usando a permissão de acesso ao armazenamento. Depois dessa etapa, o widget pode funcionar como esperado.
Fluxograma ilustrando o fluxo do cabeçalho de acesso ao armazenamento
Diagrama de fluxo do cabeçalho de acesso ao armazenamento.

Atualizar a solução

Com o recurso de cabeçalhos de acesso ao armazenamento, é recomendável atualizar o código em dois casos:

  1. Você usa o SAA e quer melhorar a performance com a lógica de cabeçalho.
  2. Você tem uma validação ou lógica que depende se o cabeçalho Origin está incluído na solicitação no servidor.

Implementar a lógica de cabeçalhos SAA

Para usar os cabeçalhos de acesso ao armazenamento na sua solução, você precisa atualizá-la. Suponha que você seja o proprietário de calendar.example. Para que o website.example possa carregar um widget calendar.example personalizado, o código do widget precisa ter acesso ao armazenamento.

Lado do cliente

O recurso de cabeçalhos de acesso ao armazenamento não exige nenhuma atualização de código no lado do cliente para as soluções atuais. Leia a documentação para saber como implementar a SAA.

Lado do servidor

No servidor, você pode usar os novos cabeçalhos:

app.get('/cookie-access-endpoint', (req, res) => {
  const storageAccessHeader = req.headers['sec-fetch-storage-access'];

  if (storageAccessHeader === 'inactive') {
    // User needs to grant permission, trigger a prompt
    if (!validate_origin(req.headers.origin)) {
      res.status(401).send(`${req.headers.origin} is not allowed to send` +
          ' credentialed requests to this server.');
      return;
    }
    res.set('Activate-Storage-Access', `retry; allowed-origin="${req.headers.origin}"`);
    res.status(401).send('This resource requires storage access. Please grant permission.');
  } else if (storageAccessHeader === 'active') {
    // User has granted permission, proceed with access
    res.set('Activate-Storage-Access', 'load');
    // Include the actual iframe content here
    res.send('This is the content that requires cookie access.');
  } else {
    // Handle other cases (e.g., 'Sec-Fetch-Storage-Access': 'none')
  }
});

Confira a demonstração para saber como essa solução funciona na prática.

Atualizar a lógica do cabeçalho de origem

Com os cabeçalhos de acesso ao armazenamento, o Chrome envia o cabeçalho Origin em mais solicitações do que antes. Isso pode afetar a lógica do servidor se ela depender de que o cabeçalho "Origin" esteja presente apenas para tipos específicos de solicitações (como as definidas por CORS).

Para evitar possíveis problemas, revise o código do servidor:

  • Verifique se há alguma validação ou lógica que depende da presença do cabeçalho Origin.
  • Atualize seu código para processar o cabeçalho Origin presente em mais casos.

Principais vantagens

Os cabeçalhos de acesso ao armazenamento são uma maneira recomendada e mais eficiente de usar o SAA. No geral, essa mudança traz várias melhorias:

  • Suporte a incorporação sem iframe:permite o SAA para uma gama mais ampla de recursos.
  • Uso reduzido da rede:menos solicitações e payloads menores.
  • Menor uso da CPU:menos processamento de JavaScript.
  • Melhoria na UX:elimina as cargas intermediárias que interrompem a navegação.

Participar do teste de origem

Com eles, você pode testar novos recursos e fornecer feedback sobre usabilidade, praticidade e eficácia. Para mais informações, consulte Começar a usar os testes de origem.

Para testar o recurso de cabeçalhos de acesso ao armazenamento, inscreva-se nos testes de origem a partir do Chrome 130. Para participar do teste de origem:

  1. Acesse a página de registro do teste de origem dos cabeçalhos de acesso ao Storage.
  2. Siga as instruções sobre a participação no teste de origem.

Testar localmente

Você pode testar o recurso de cabeçalhos de acesso ao armazenamento localmente para garantir que seu site esteja preparado para essa mudança.

Siga estas etapas para configurar sua instância do Chrome:

  1. Ative a flag do Chrome em chrome://flags/#storage-access-headers.
  2. Reinicie o Chrome para que as mudanças entrem em vigor.

Engajamento e compartilhamento de feedback

Se você tiver feedback ou encontrar algum problema, registre um problema. Saiba mais sobre os cabeçalhos de acesso ao armazenamento no GitHub.