Conjuntos de sites relacionados: guia para desenvolvedores

Os conjuntos de sites relacionados (RWS, na sigla em inglês) são um mecanismo de plataforma da Web que ajuda os navegadores a entender as relações entre um conjunto de domínios. Isso permite que os navegadores tomem decisões importantes para ativar determinadas funções do site (por exemplo, permitir o acesso a cookies entre sites) e apresentar essas informações aos usuários.

À medida que o Chrome descontinuar os cookies de terceiros, o objetivo dele é manter os principais casos de uso na Web e melhorar a privacidade dos usuários. Por exemplo, muitos sites dependem de vários domínios para atender a uma única experiência do usuário. Talvez as organizações queiram manter diferentes domínios de nível superior para vários casos de uso, como domínios específicos de um país ou domínios de serviço para hospedagem de imagens ou vídeos. Os conjuntos de sites relacionados permitem que os sites compartilhem dados entre domínios, com controles específicos.

De modo geral, um conjunto de sites relacionados é um conjunto de domínios em que há um único "conjunto primário" e possivelmente vários "membros do conjunto".

No exemplo a seguir, primary lista o domínio principal, e associatedSites lista os domínios que atendem aos requisitos do subconjunto associado.

{
  "primary": "https://primary.com",
  "associatedSites": ["https://associate1.com", "https://associate2.com", "https://associate3.com"]
}

A lista canônica de conjuntos de sites relacionados é uma lista disponível publicamente em um formato de arquivo JSON hospedado no repositório de conjuntos de sites relacionados do GitHub (link em inglês), que serve como a fonte da verdade para todos os conjuntos. O Chrome usa esse arquivo para aplicar ao comportamento dele.

Somente as pessoas com controle administrativo sobre um domínio podem criar um conjunto com ele. Os desenvolvedores precisam declarar a relação entre cada "membro do conjunto" e o "conjunto principal". Os membros do conjunto podem incluir vários tipos de domínio e precisam fazer parte de um subconjunto com base em um caso de uso.

Caso seu aplicativo dependa do acesso a cookies entre sites (também chamados de cookies de terceiros) entre sites dentro do mesmo conjunto de sites relacionados, use a API Storage Access (SAA) e a API requestStorageAccessFor para solicitar o acesso a esses cookies. Dependendo do subconjunto do qual cada site faz parte, o navegador pode processar a solicitação de forma diferente.

Para saber mais sobre o processo e os requisitos para envio de conjuntos, confira as diretrizes de envio. Os conjuntos enviados passarão por várias verificações técnicas para validar os envios.

Os conjuntos de sites relacionados são uma boa opção para casos em que uma organização precisa de uma forma de identidade compartilhada em diferentes sites de nível superior.

Alguns dos casos de uso para conjuntos de sites relacionados são:

  • Personalização de país. Aproveitar sites localizados e contar com a infraestrutura compartilhada (example.co.uk pode depender de um serviço hospedado por example.ca).
  • Integração do domínio de serviço. Aproveitar domínios de serviço com os quais os usuários nunca interagem diretamente, mas fornecem serviços nos sites da mesma organização (example-cdn.com).
  • Separação de conteúdo do usuário. Acessar dados em domínios diferentes que separam o conteúdo enviado pelo usuário de outros conteúdos do site por motivos de segurança, ao mesmo tempo em que permite que o domínio em sandbox acesse a autenticação (e outros) cookies. Se você veicular conteúdo inativo enviado por usuários, também poderá hospedar esse conteúdo com segurança no mesmo domínio seguindo as práticas recomendadas.
  • Conteúdo autenticado incorporado. oferecer suporte a conteúdo incorporado de diversas propriedades afiliadas (vídeos, documentos ou recursos restritos ao usuário conectado no site de nível superior).
  • Fazer login. Compatibilidade com o login em propriedades afiliadas. A API FedCM também pode ser adequada para alguns casos de uso.
  • Análise de dados. Implantar análises e medições das jornadas dos usuários em propriedades afiliadas para melhorar a qualidade dos serviços.

API Storage Access

Compatibilidade com navegadores

  • 119
  • 85
  • 65
  • 11.1

Origem

A API Storage Access (SAA) oferece uma maneira de o conteúdo de origem cruzada incorporado acessar o armazenamento que normalmente teria acesso apenas em um contexto próprio.

Os recursos incorporados podem usar métodos de SAA para verificar se têm acesso ao armazenamento e solicitar acesso ao user agent.

Quando os cookies de terceiros são bloqueados, mas os conjuntos de sites relacionados (RWS) estão ativados, o Chrome concede permissão automaticamente em contextos intra-RWS e mostra uma solicitação ao usuário. Um "contexto intra-RWS" é um contexto, como um iframe, em que o site incorporado e o site de nível superior estão no mesmo RWS.

Verificar e solicitar acesso ao armazenamento

Para verificar se eles têm acesso ao armazenamento, os sites incorporados podem usar o método Document.hasStorageAccess().

O método retorna uma promessa que é resolvida com um valor booleano indicando se o documento já tem acesso aos cookies ou não. A promessa também vai retornar "true" se o iframe for da mesma origem que o frame superior.

Para pedir acesso a cookies em um contexto incorporado entre sites, use o Document.requestStorageAccess() (rSA).

A API requestStorageAccess() precisa ser chamada de um iframe. Esse iframe precisa ter acabado de receber interação do usuário (um gesto do usuário, que é exigido por todos os navegadores), mas o Chrome também exige que, nos últimos 30 dias, o usuário tenha visitado o site proprietário do iframe e interagido com esse site especificamente, como um documento de nível superior, não em um iframe.

requestStorageAccess() retorna uma promessa que será resolvida se o acesso ao armazenamento tiver sido concedido. A promessa é rejeitada, citando o motivo, se o acesso foi negado por qualquer motivo.

requestStorageAccessFor no Chrome

Compatibilidade com navegadores

  • 119
  • 119
  • x
  • x

Origem

A API Storage Access só permite que sites incorporados solicitem acesso ao armazenamento usando elementos <iframe> que receberam a interação do usuário.

Isso traz desafios na adoção da API Storage Access para sites de nível superior que usam imagens entre sites ou tags de script que exigem cookies.

Para resolver isso, o Chrome implementou uma maneira para sites de nível superior solicitarem acesso ao armazenamento em nome de origens específicas com Document.requestStorageAccessFor() (rSAFor).

 document.requestStorageAccessFor('https://target.site')

A API requestStorageAccessFor() precisa ser chamada por um documento de nível superior. Esse documento também precisa ter acabado de receber a interação do usuário. Mas, diferentemente de requestStorageAccess(), o Chrome não verifica se houve uma interação em um documento de nível superior nos últimos 30 dias porque o usuário já está na página.

Verificar as permissões de acesso ao armazenamento

O acesso a alguns recursos do navegador, como câmera ou geolocalização, é baseado nas permissões concedidas pelo usuário. A API Permissions fornece uma maneira de verificar o status da permissão para acessar uma API, se ela foi concedida, negada ou se exige alguma forma de interação do usuário, como clicar em um comando ou interagir com a página.

É possível consultar o status de permissão usando navigator.permissions.query().

Para verificar a permissão de acesso ao armazenamento para o contexto atual, você precisa transmitir a string 'storage-access':

navigator.permissions.query({name: 'storage-access'})

Para verificar a permissão de acesso ao armazenamento de uma origem especificada, você precisa transmitir a string 'top-level-storage-access':

navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'})

Para proteger a integridade da origem incorporada, isso verifica apenas as permissões concedidas pelo documento de nível superior usando document.requestStorageAccessFor.

Se a permissão puder ser concedida automaticamente ou exigir um gesto do usuário, ela vai retornar prompt ou granted.

Por modelo de frame

As concessões de rSA são aplicadas por frame. Essas concessões são tratadas como permissões separadas.

Cada novo frame precisará solicitar acesso ao armazenamento individualmente, e o acesso será concedido automaticamente. Somente a primeira solicitação exige um gesto do usuário. As solicitações subsequentes iniciadas pelo iframe, como navegação ou sub-recursos, não precisarão aguardar um gesto do usuário, já que ele será concedido à sessão de navegação pela solicitação inicial.

Para atualizar, recarregar ou recriar o iframe, será necessário solicitar acesso novamente.

Os cookies precisam especificar os atributos SameSite=None e Secure, já que a rSA só oferece acesso a cookies já marcados para uso em contextos entre sites.

Cookies com SameSite=Lax, SameSite=Strict ou sem um atributo SameSite são apenas para uso próprio e nunca serão compartilhados em um contexto entre sites, independentemente da rSA.

Segurança

Para rSAFor, as solicitações de sub-recursos exigem cabeçalhos de Compartilhamento de recursos entre origens (CORS) ou o atributo crossorigin nos recursos, garantindo a ativação explícita.

Exemplos de implementação

Solicitar acesso ao armazenamento de um iframe incorporado de origem cruzada

Diagrama mostrando um site incorporado em um site de nível superior
Usar requestStorageAccess() na incorporação de outro site.

Verificar se você tem acesso ao armazenamento

Para verificar se você já tem acesso ao armazenamento, use document.hasStorageAccess().

Se a promessa for resolvida como verdadeira, você poderá acessar o armazenamento no contexto entre sites. Se ela for resolvida como "false", será necessário solicitar acesso ao armazenamento.

document.hasStorageAccess().then((hasAccess) => {
    if (hasAccess) {
      // You can access storage in this context
    } else {
      // You have to request storage access
    }
});

Solicitar acesso ao armazenamento

Se você precisar solicitar acesso ao armazenamento, verifique primeiro a permissão navigator.permissions.query({name: 'storage-access'}) para saber se ela exige um gesto do usuário ou se pode ser concedida automaticamente.

Se a permissão for granted, você poderá chamar document.requestStorageAccess(). O resultado será bem-sucedido sem um gesto do usuário.

Se o status de permissão for prompt, será necessário iniciar a chamada document.requestStorageAccess() após um gesto do usuário, como um clique de botão.

Exemplo:

navigator.permissions.query({name: 'storage-access'}).then(res => {
  if (res.state === 'granted') {
    // Permission has already been granted
    // You can request storage access without any user gesture
    rSA();
  } else if (res.state === 'prompt') {
    // Requesting storage access requires user gesture
    // For example, clicking a button
    const btn = document.createElement("button");
    btn.textContent = "Grant access";
    btn.addEventListener('click', () => {
      // Request storage access
      rSA();
    });
    document.body.appendChild(btn);
  }
});

function rSA() {
  if ('requestStorageAccess' in document) {
    document.requestStorageAccess().then(
      (res) => {
        // Use storage access
      },
      (err) => {
        // Handle errors
      }
    );
  }
}

As solicitações subsequentes do frame, navegações ou sub-recursos terão permissão automática para acessar cookies entre sites. hasStorageAccess() retorna cookies verdadeiros e entre sites do mesmo conjunto de sites relacionados que vão ser enviados nessas solicitações sem outras chamadas JavaScript.

Diagrama mostrando requestStorageAccessFor() sendo usado em um site de nível superior e não em uma incorporação
Como usar requestStorageAccessFor() em um site de nível superior para uma origem diferente

Sites de nível superior podem usar requestStorageAccessFor() para solicitar acesso ao armazenamento em nome de origens específicas.

O hasStorageAccess() só verifica se o site que o chama tem acesso de armazenamento. Assim, um site de nível superior pode verificar as permissões de outra origem.

Para descobrir se o usuário receberá uma solicitação ou se o acesso ao armazenamento já foi concedido à origem especificada, chame navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'}).

Se a permissão for granted, chame document.requestStorageAccessFor('https://target.site'). Ele precisa ser bem-sucedido sem um gesto do usuário.

Se a permissão for prompt, você precisará vincular a chamada de document.requestStorageAccessFor('https://target.site') atrás do gesto do usuário, como um clique de botão.

Exemplo:

navigator.permissions.query({name:'top-level-storage-access',requestedOrigin: 'https://target.site'}).then(res => {
  if (res.state === 'granted') {
    // Permission has already been granted
    // You can request storage access without any user gesture
    rSAFor();
  } else if (res.state === 'prompt') {
    // Requesting storage access requires user gesture
    // For example, clicking a button
    const btn = document.createElement("button");
    btn.textContent = "Grant access";
    btn.addEventListener('click', () => {
      // Request storage access
      rSAFor();
    });
    document.body.appendChild(btn);
  }
});

function rSAFor() {
  if ('requestStorageAccessFor' in document) {
    document.requestStorageAccessFor().then(
      (res) => {
        // Use storage access
      },
      (err) => {
        // Handle errors
      }
    );
  }
}

Após uma chamada requestStorageAccessFor() bem-sucedida, as solicitações entre sites vão incluir cookies se tiverem CORS ou o atributo de origem cruzada. Por isso, os sites podem esperar antes de acionar uma solicitação.

As solicitações precisam usar a opção credentials: 'include', e os recursos precisam incluir o atributo crossorigin="use-credentials".

function checkCookie() {
    fetch('https://related-website-sets.glitch.me/getcookies.json', {
        method: 'GET',
        credentials: 'include'
      })
      .then((response) => response.json())
      .then((json) => {
      // Do something
      });
  }

Como testar localmente

Pré-requisitos

Para testar os conjuntos de sites relacionados localmente, use o Chrome 119 ou versão mais recente iniciado na linha de comando e ative a sinalização test-third-party-cookie-phaseout do Chrome.

Ativar a flag do Chrome

Para ativar a sinalização necessária do Chrome, acesse chrome://flags#test-third-party-cookie-phaseout na barra de endereço e mude a flag para Enabled. Reinicie o navegador depois de alterar as sinalizações.

Para iniciar o Chrome com o conjunto de sites relacionados declarado localmente, crie um objeto JSON que contenha os URLs que são membros de um conjunto e transmita-o para --use-related-website-set.

Saiba mais sobre como executar o Chromium com sinalizações.

--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/

Exemplo

Para ativar os conjuntos de sites relacionados localmente, ative o test-third-party-cookie-phaseout em chrome://flags e inicie o Chrome pela linha de comando com a sinalização --use-related-website-set com o objeto JSON que contém os URLs que são membros de um conjunto.

--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/

Verificar se você tem acesso a cookies entre sites

Chame as APIs (rSA ou rSAFor) dos sites que estão sendo testados e valide o acesso aos cookies entre sites.

Para declarar a relação entre domínios e especificar de qual subconjunto eles fazem parte, siga estas etapas:

  1. Identifique os domínios relevantes, incluindo os membros definidos como principais e os membros do conjunto que fazem parte do conjunto de sites relacionados. Identifique também a que tipo de subconjunto cada membro do conjunto pertence.
  2. Confira se os requisitos de formação definidos e os de validação definidos estão em vigor.
  3. Declare o conjunto de sites relacionados no formato JSON correto.
  4. Envie o conjunto de sites relacionados criando uma solicitação de envio (PR, na sigla em inglês) para o related_website_sets.JSON em que o Chrome vai hospedar a lista canônica de sites relacionados. É necessário ter uma conta do GitHub para criar PRs, e você precisará assinar um Contrato de licença de colaborador (CLA, na sigla em inglês) para contribuir com a lista.

Depois que o RP é criado, uma série de verificações acontece para validar se os requisitos da etapa 2 foram atendidos.

Se bem-sucedido, o PR vai indicar que as verificações foram aprovadas. Os PRs aprovados serão mesclados manualmente em lotes à lista canônica de sites relacionados uma vez por semana (terças-feiras às 12h, horário da Costa Leste dos EUA).

Se alguma das verificações falhar, o remetente será notificado por uma falha de RP no GitHub. O remetente poderá corrigir os erros e atualizar o PR, tendo em mente o seguinte:

  • Quando o PR falha, uma mensagem de erro fornece mais informações sobre o motivo da falha no envio (exemplo).
  • Todas as verificações técnicas que regem os envios de conjuntos são realizadas no GitHub e, consequentemente, todas as falhas de envio resultantes de verificações técnicas ficarão visíveis no GitHub.

Políticas empresariais

Para atender às necessidades de usuários corporativos, o Chrome tem algumas políticas corporativas em vigor:

  • Os sistemas que não podem ser integrados aos conjuntos de sites relacionados podem desativar esse recurso em todas as instâncias corporativas do Chrome com a política RelatedWebsiteSetsEnabled.
  • Alguns sistemas empresariais têm sites somente internos (como uma intranet) com domínios registráveis que são diferentes dos domínios no conjunto de sites relacionados. Se for preciso tratar esses sites como parte do conjunto de sites relacionados sem expô-los publicamente (já que os domínios podem ser confidenciais), eles poderão aumentar ou substituir a lista pública de conjuntos de sites relacionados pela política RelatedWebsiteSetsOverrides.

"Solicitação do usuário" e "gesto do usuário"

Uma "solicitação do usuário" e um "gesto do usuário" são coisas diferentes. O Chrome não mostra uma solicitação de permissão aos usuários para sites que estão no mesmo conjunto de sites relacionados, mas ainda exige que o usuário tenha interagido com a página. Antes de conceder a permissão, o Chrome exige um gesto do usuário, também chamado de "interação do usuário" ou "ativação do usuário". Isso ocorre porque o uso da API Storage Access fora de um contexto de conjunto de sites relacionados (ou seja, requestStorageAccess()) também exige um gesto do usuário devido aos princípios de design da plataforma da Web.

Acessar cookies ou armazenamento de outros sites

Os conjuntos de sites relacionados não mesclam o armazenamento de sites diferentes, apenas permitem chamadas requestStorageAccess() mais fáceis (sem solicitação). Os conjuntos de sites relacionados apenas reduzem o atrito do usuário no uso da API Storage Access, mas não ditam o que fazer depois que o acesso é restaurado. Se A e B forem sites diferentes no mesmo conjunto de sites relacionados e A incorporar B, B vai poder chamar requestStorageAccess() e ter acesso ao armazenamento próprio sem pedir ao usuário. Os conjuntos de sites relacionados não realizam comunicação entre sites. Por exemplo, definir um conjunto de sites relacionados não vai fazer com que os cookies pertencentes a B comecem a ser enviados a A. Se você quiser compartilhar esses dados, terá que fazer isso por conta própria, por exemplo, enviando um window.postMessage de um iframe B para um frame A.

Os conjuntos de sites relacionados não permitem o acesso implícito a cookies não particionados sem invocar qualquer API. Os cookies entre sites não são disponibilizados por padrão no conjunto. Os conjuntos de sites relacionados só permitem que os sites no conjunto ignorem a solicitação de permissão da API Storage Access. Um iframe precisa chamar document.requestStorageAccess() se quiser acessar os cookies. Caso contrário, a página de nível superior pode chamar document.requestStorageAccessFor().

Compartilhar feedback

Enviar um conjunto no GitHub e trabalhar com a API Storage Access e a API requestStorageAccessFor são oportunidades de compartilhar sua experiência com o processo e os problemas que você encontrou.

Para participar de discussões sobre conjuntos de sites relacionados: