API Storage Access

O bloqueio de cookies de terceiros por navegadores, configurações do usuário e particionamento de armazenamento é um desafio para sites e serviços que dependem de cookies e outros armazenamentos em contextos incorporados para jornadas do usuário, como autenticação. A API Storage Access (SAA) permite que esses casos de uso continuem funcionando, limitando o máximo possível o rastreamento entre sites.

Status da implementação

Compatibilidade com navegadores

  • Chrome: 119
  • Edge: 85.
  • Firefox: 65.
  • Safari: 11.1.

Origem

A API Storage Access está disponível em todos os principais navegadores, mas existem pequenas diferenças de implementação entre eles. Essas diferenças foram destacadas nas seções relevantes nesta postagem.

Estamos trabalhando para resolver todos os problemas de bloqueio restantes antes de padronizar a API.

O que é a API Storage Access?

A API Storage Access é uma API JavaScript que permite que os iframes solicitem permissões de acesso ao armazenamento quando o acesso seria negado pelas configurações do navegador. Incorporações com casos de uso que dependem do carregamento de recursos entre sites podem usar a API para solicitar a permissão de acesso do usuário, conforme necessário.

Se a solicitação de armazenamento for concedida, o iframe terá acesso aos cookies e armazenamento não particionados, que também ficam disponíveis quando os usuários o acessam como um site de nível superior.

A API Storage Access permite que o acesso a cookies e armazenamento não particionados específicos seja fornecido com o mínimo de sobrecarga para o usuário final, além de impedir o acesso a cookies e armazenamento não particionados genéricos, que geralmente são usados para rastrear usuários.

Casos de uso

Algumas incorporações de terceiros exigem acesso a cookies ou armazenamento não particionados para oferecer uma experiência melhor ao usuário. Isso não vai estar disponível quando os cookies de terceiros forem restritos e o particionamento de armazenamento estiver ativado.

Os casos de uso incluem o seguinte:

  • Widgets de comentários incorporados que exigem detalhes da sessão de login.
  • "Gostei" em mídias sociais que exigem detalhes da sessão de login.
  • Documentos incorporados que exigem detalhes da sessão de login.
  • Uma experiência premium fornecida a uma incorporação de vídeo (por exemplo, para não mostrar anúncios a usuários conectados, para saber as preferências do usuário com legendas ou para restringir certos tipos de vídeo).
  • Sistemas de pagamento incorporados.

Muitos desses casos de uso envolvem a persistência do acesso de login em iframes incorporados.

Quando usar a API Storage Access em vez de outras APIs

A API Storage Access é uma das alternativas para usar cookies e armazenamento não particionados. Por isso, é importante entender quando usar essa API em comparação com as outras. Ela é destinada a casos de uso em que as duas condições a seguir são verdadeiras:

  • O usuário vai interagir com o conteúdo incorporado, ou seja, não é um iframe passivo ou oculto.
  • O usuário visitou a origem incorporada em um contexto de nível superior, ou seja, quando essa origem não está incorporada em outro site.

Existem APIs alternativas para diversos casos de uso:

  • Cookies com estado particionado independente (CHIPS, na sigla em inglês) permite que os desenvolvedores ativem um cookie para "particionamento" armazenamento, com um cookie jar separado por site de nível superior. Por exemplo, um widget de chat na Web de terceiros pode depender da configuração de um cookie para salvar informações da sessão. As informações de sessão são salvas por site, portanto, o cookie definido pelo widget não precisa ser acessado em outros sites onde também está incorporado. A API Storage Access é útil quando um widget de terceiros incorporado depende do compartilhamento das mesmas informações em diferentes origens (por exemplo, para detalhes ou preferências de sessão de login).
  • O particionamento de armazenamento é uma forma dos iframes entre sites usarem mecanismos de armazenamento JavaScript existentes ao dividir o armazenamento subjacente por site. Isso impede que o armazenamento incorporado em um site seja acessado pela mesma incorporação em outros sites.
  • Os conjuntos de sites relacionados (RWS, na sigla em inglês) são uma forma de uma organização declarar relações entre sites para que os navegadores permitam um acesso limitado a cookies e armazenamento não particionados para fins específicos. Os sites ainda precisam solicitar acesso com a API Storage Access, mas, para sites no conjunto, o acesso pode ser concedido sem solicitações do usuário.
  • O Federated Credential Management (FedCM) é uma abordagem dos serviços de identidade federada que preserva a privacidade. A API Storage Access lida com o acesso a cookies não particionados e ao armazenamento após o login. Em alguns casos de uso, o FedCM é uma solução alternativa à API Storage Access e pode ser preferível porque apresenta um prompt do navegador mais orientado a login. No entanto, adotar o FedCM geralmente exige outras mudanças no código, por exemplo, para oferecer suporte aos endpoints HTTP.
  • Também existem APIs antifraude, relacionadas a anúncios e de medição, e a API Storage Access não foi criada para resolver essas questões.

Usar a API Storage Access

A API Storage Access tem dois métodos baseados em promessas:

Ele também se integra à API Permissions. Isso permite verificar o status da permissão de acesso ao armazenamento em um contexto de terceiros, o que indica se uma chamada para document.requestStorageAccess() seria concedida automaticamente:

Usar o método hasStorageAccess()

Quando um site é carregado pela primeira vez, ele pode usar o método hasStorageAccess() para verificar se o acesso a cookies de terceiros já foi concedido.

// Set a hasAccess boolean variable which defaults to false.
let hasAccess = false;

async function handleCookieAccessInit() {
  if (!document.hasStorageAccess) {
    // Storage Access API is not supported so best we can do is
    // hope it's an older browser that doesn't block 3P cookies.
    hasAccess = true;
  } else {
    // Check whether access has been granted using the Storage Access API.
    // Note on page load this will always be false initially so we could be
    // skipped in this example, but including for completeness for when this
    // is not so obvious.
    hasAccess = await document.hasStorageAccess();
    if (!hasAccess) {
      // Handle the lack of access (covered later)
    }
  }
  if (hasAccess) {
    // Use the cookies.
  }
}
handleCookieAccessInit();

O acesso ao armazenamento só é concedido a um documento iframe depois que ele chama requestStorageAccess(),. Portanto, hasStorageAccess() sempre retornará "false" inicialmente, exceto quando outro documento de mesma origem no mesmo iframe já tiver recebido acesso. A concessão é preservada em navegações de mesma origem no iframe especificamente para permitir atualizações após conceder acesso a páginas que exigem a presença de cookies na solicitação inicial do documento HTML.

Usar requestStorageAccess()

Se o iframe não tiver acesso, talvez seja necessário solicitar acesso usando o método requestStorageAccess():

if (!hasAccess) {
  try {
    await document.requestStorageAccess();
  } catch (err) {
    // Access was not granted and it may be gated behind an interaction
    return;
  }
}

Na primeira vez que isso for solicitado, o usuário talvez precise aprovar o acesso com uma solicitação do navegador. Depois disso, a promessa vai ser resolvida ou rejeitada, resultando em uma exceção se await for usada.

Para evitar abusos, essa solicitação do navegador só será exibida após uma interação do usuário. É por isso que requestStorageAccess() precisa ser chamado inicialmente de um manipulador de eventos ativado pelo usuário, em vez de imediatamente após o carregamento do iframe:

async function doClick() {

  // Only do this extra check if access hasn't already been given
  // based on the hasAccess variable.
  if (!hasAccess) {
    try {
      await document.requestStorageAccess();
      hasAccess = true; // Can assume this was true if requestStorageAccess() did not reject.
    } catch (err) {
      // Access was not granted.
      return;
    }
  }

  if (hasAccess) {
    // Use the cookies
  }
}

document.querySelector('#my-button').addEventListener('click', doClick);

Se você precisar usar o armazenamento local em vez de cookies, faça o seguinte:

let handle = null;

async function doClick() {
  if (!handle) {
    try {
      handle = await document.requestStorageAccess({localStorage: true});
    } catch (err) {
      // Access was not granted.
      return;
    }
  }

  // Use handle to access unpartitioned local storage.
  handle.localStorage.setItem('foo', 'bar');
}

document.querySelector('#my-button').addEventListener('click', doClick);

Solicitações de permissão

Quando o usuário clicar no botão pela primeira vez, a solicitação do navegador aparecem automaticamente, normalmente na barra de endereço. A captura de tela a seguir mostra um exemplo de solicitação do Chrome, mas outros navegadores têm uma interface semelhante:

Solicitação de permissão da API Storage Access do Chrome
Solicitação de permissão da API Storage Access do Chrome

O navegador pode pular a solicitação e fornecer a permissão automaticamente em determinadas circunstâncias:

  • Se a página e o iframe foram usados nos últimos 30 dias após aceitar a solicitação.
  • Se o iframe incorporado faz parte de um conjunto de sites relacionados.
  • No Firefox, a solicitação também é ignorada para sites conhecidos (aqueles com os quais você interagiu no nível superior) nas primeiras cinco tentativas.

Como alternativa, o método pode ser rejeitado automaticamente sem mostrar a solicitação em determinadas circunstâncias:

  • Se o usuário nunca visitou e interagiu com o site que tem o iframe como um documento de nível superior, não em um iframe. Isso significa que a API Storage Access é útil apenas para sites incorporados que os usuários já visitaram em um contexto próprio.
  • Se o método requestStorageAccess() for chamado fora de um evento de interação do usuário sem aprovação prévia da solicitação após uma interação.

Embora o usuário receba uma solicitação no uso inicial, as visitas subsequentes podem resolver requestStorageAccess() sem uma solicitação e sem exigir interação do usuário no Chrome e no Firefox. O Safari sempre requer uma interação do usuário.

Como o acesso a cookies e armazenamento pode ser concedido sem uma solicitação ou interação do usuário, muitas vezes é possível receber acesso a cookies ou armazenamento não particionado antes de uma interação do usuário em navegadores compatíveis (Chrome e Firefox) chamando requestStorageAccess() no carregamento da página. Isso pode permitir que você acesse cookies e armazenamento não particionados imediatamente e ofereça uma experiência mais completa, mesmo antes do usuário interagir com o iframe. Em algumas situações, isso pode oferecer uma experiência melhor do que esperar pela interação do usuário.

Usar a consulta de permissão storage-access

Para verificar se o acesso pode ser concedido sem uma interação do usuário, verifique o status da permissão storage-access e faça a chamada requestStoreAccess() antecipadamente apenas se nenhuma ação do usuário for necessária, em vez de fazer a chamada e ter falha quando uma interação for necessária.

Isso também permite que você lide com a necessidade de uma solicitação antecipadamente mostrando conteúdos diferentes, como um botão de login.

O código a seguir adiciona a verificação de permissão storage-access ao exemplo anterior:

// Set a hasAccess boolean variable which defaults to false except for
// browsers which don't support the API - where we assume
// such browsers also don't block third-party cookies.
let hasAccess = false;

async function hasCookieAccess() {
  // Check if Storage Access API is supported
  if (!document.requestStorageAccess) {
    // Storage Access API is not supported so best we can do is
    // hope it's an older browser that doesn't block 3P cookies.
    return true;
  }

  // Check if access has already been granted
  if (await document.hasStorageAccess()) {
    return true;
  }

  // Check the storage-access permission
  // Wrap this in a try/catch for browsers that support the
  // Storage Access API but not this permission check
  // (e.g. Safari and earlier versions of Firefox).
  let permission;
  try {
    permission = await navigator.permissions.query(
      {name: 'storage-access'}
    );
  } catch (error) {
    // storage-access permission not supported. Assume no cookie access.
    return false;
  }

    if (permission) {
    if (permission.state === 'granted') {
      // Permission has previously been granted so can just call
      // requestStorageAccess() without a user interaction and
      // it will resolve automatically.
      try {
        await document.requestStorageAccess();
        return true;
      } catch (error) {
        // This shouldn't really fail if access is granted, but return false
        // if it does.
        return false;
      }
    } else if (permission.state === 'prompt') {
      // Need to call requestStorageAccess() after a user interaction
      // (potentially with a prompt). Can't do anything further here,
      // so handle this in the click handler.
      return false;
          } else if (permission.state === 'denied') {
            // Not used: see https://github.com/privacycg/storage-access/issues/149
      return false;
          }
    }

  // By default return false, though should really be caught by earlier tests.
  return false;
}

async function handleCookieAccessInit() {
  hasAccess = await hasCookieAccess();

  if (hasAccess) {
    // Use the cookies.
  }
}

handleCookieAccessInit();

Iframes no modo sandbox

Ao usar a API Storage Access em iframes no modo sandbox, as seguintes permissões de sandbox são necessárias:

  • O allow-storage-access-by-user-activation é necessário para permitir o acesso à API Storage Access.
  • O allow-scripts é necessário para permitir que o JavaScript chame a API.
  • O allow-same-origin é necessário para permitir o acesso a cookies da mesma origem e outro armazenamento.

Exemplo:

<iframe sandbox="allow-storage-access-by-user-activation
                 allow-scripts
                 allow-same-origin"
        src="..."></iframe>

Para serem acessados com a API Storage Access no Chrome, os cookies entre sites precisam ser definidos com os dois atributos a seguir:

  • SameSite=None: necessário para marcar o cookie como "entre sites"
  • Secure: garante que apenas cookies definidos por sites HTTPS possam ser acessados.

No Firefox e no Safari, os cookies são definidos como SameSite=None por padrão e não restringem o SAA a cookies Secure. Portanto, esses atributos não são necessários. É recomendável ser explícito sobre o atributo SameSite e sempre usar cookies Secure.

Acesso à página de nível superior

A API Storage Access tem como objetivo ativar o acesso a cookies de terceiros em iframes incorporados.

Há também outros casos de uso em que a página de nível superior exige acesso a cookies de terceiros. Por exemplo, imagens ou scripts restritos por cookies e que os proprietários de sites querem incluir diretamente no documento de nível superior em vez de em um iframe. Para resolver esse caso de uso, o Chrome propôs uma extensão para a API Storage Access que adiciona um método requestStorageAccessFor().

O método requestStorageAccessFor()

Compatibilidade com navegadores

  • Chrome: 119.
  • Borda: 119.
  • Firefox: incompatível.
  • Safari: incompatível.

Origem

O método requestStorageAccessFor() funciona de maneira semelhante a requestStorageAccess(), mas para recursos de nível superior. Ela só pode ser usada em sites em um conjunto de sites relacionados para impedir o acesso geral a cookies de terceiros.

Para mais detalhes sobre como usar o requestStorageAccessFor(), leia Conjuntos de sites relacionados: guia para desenvolvedores.

A consulta de permissão top-level-storage-access

Compatibilidade com navegadores

  • Chrome: incompatível.
  • Edge: não é compatível.
  • Firefox: incompatível.
  • Safari: incompatível.

Semelhante à permissão storage-access, há uma permissão top-level-storage-access para verificar se o acesso pode ser concedido para requestStorageAccessFor().

Qual é a diferença da API Storage Access quando usada com RWS?

Quando conjuntos de sites relacionados são usados com a API Storage Access, alguns recursos extras são disponibilizados, conforme detalhado na tabela a seguir:

Sem RWS Com RWS
Exige um gesto do usuário para iniciar a solicitação de acesso ao armazenamento
Exige que o usuário visite a origem de armazenamento solicitada em um contexto de nível superior antes de conceder acesso
É possível pular o primeiro comando do usuário
requestStorageAccess não precisa ser chamado se o acesso já tiver sido concedido
Concede acesso automaticamente a outros domínios em um site relacionado
Oferece suporte a requestStorageAccessFor para acesso à página de nível superior
Diferenças entre o uso da API Storage Access com e sem conjuntos de sites relacionados

Demonstração: como configurar e acessar cookies

A demonstração a seguir mostra como um cookie definido por você na primeira tela da demonstração pode ser acessado em um frame incorporado no segundo site:

storage-access-api-demo.glitch.me

A demonstração requer um navegador com cookies de terceiros desativados:

  • Chrome 118 ou mais recente com a flag chrome://flags/#test-third-party-cookie-phaseout definida e o navegador reiniciado.
  • Firefox
  • Safari

Demonstração: como configurar o armazenamento local

A demonstração a seguir mostra como acessar canais de transmissão não particionados a partir de um iframe de terceiros usando a API Storage Access:

https://saa-beyond-cookies.glitch.me/

A demonstração exige o Chrome 125 ou mais recente com a flag test-third-party-cookie-phaseout ativada.

Recursos