Migrar para as dicas de cliente do user agent

Estratégias para migrar seu site de depender da string user agent para o novas dicas de cliente HTTP do user agent.

O User-Agent string é um uso significativo de técnicas de impressão digital passivas nos navegadores, como além de serem difíceis de processar. No entanto, há todos os tipos de modelos motivos para coletar e processar dados do user agent, então é necessário um caminho para uma solução melhor. As dicas de cliente HTTP do user agent são uma forma explícita para declarar a necessidade de dados e métodos de user agent para retornar os dados em um em um formato fácil de usar.

Este artigo vai conduzir você pela auditoria de seu acesso aos dados do user agent e migração do uso da string do user agent para dicas de cliente do user agent

Coleta e uso de dados do user agent

Como acontece com qualquer forma de coleta de dados, é sempre necessário entender por que você que os coletam. A primeira etapa, independentemente de você estar ou não tomar qualquer ação é entender onde e por que você está usando os dados do user agent.

Se você não souber se ou onde os dados do user agent estão sendo usados, faça uma pesquisa seu código de front-end para usar navigator.userAgent e seu código de back-end para use o cabeçalho HTTP User-Agent. Verifique também seu código de front-end para o uso de recursos já descontinuados, como navigator.platform e navigator.appVersion.

De um ponto de vista funcional, pense em qualquer parte do código em que você esteja gravação ou processamento:

  • Nome ou versão do navegador
  • Nome ou versão do sistema operacional
  • Marca ou modelo do dispositivo
  • tipo de CPU, arquitetura ou quantidade de bits (por exemplo, 64 bits)

Também é provável que você esteja usando uma biblioteca ou um serviço de terceiros para e processar o user agent. Nesse caso, verifique se eles estão atualizando para oferecer suporte a dicas de cliente HTTP do user agent.

Você está usando apenas dados básicos do user agent?

O conjunto padrão de dicas de cliente HTTP do user agent inclui:

  • Sec-CH-UA: nome do navegador e versão principal/significativa.
  • Sec-CH-UA-Mobile: valor booleano que indica um dispositivo móvel.
  • Sec-CH-UA-Platform: nome do sistema operacional

A versão reduzida da string do user agent proposta também vai manter essas informações básicas de maneira compatível com versões anteriores. Por exemplo, em vez de Chrome/90.0.4430.85: a string incluiria Chrome/90.0.0.0.

Se você estiver verificando apenas a string do user agent para o nome do navegador, a versão principal, ou sistema operacional, seu código continuará funcionando, embora você provavelmente para ver avisos de descontinuação.

Embora você possa e deva migrar para as dicas de cliente HTTP do user agent, é possível que você tenha restrições de código ou recursos que impedem isso. A redução das informações a string do user agent dessa maneira compatível com versões anteriores tem como objetivo garantir que, embora o código existente receba informações menos detalhadas, ele ainda deve mantêm a funcionalidade básica.

Estratégia: API JavaScript sob demanda do lado do cliente

Se você estiver usando o navigator.userAgent, faça a transição para prefira navigator.userAgentData antes de voltar à análise string user agent.

if (navigator.userAgentData) {
  // use new hints
} else {
  // fall back to user-agent string parsing
}

Se você estiver verificando dispositivos móveis ou computadores, use o valor booleano mobile:

const isMobile = navigator.userAgentData.mobile;

userAgentData.brands é uma matriz de objetos com brand e version. propriedades nas quais o navegador possa listar sua compatibilidade com essas marcas. É possível acessá-lo diretamente como uma matriz ou usar um some() para verificar se há uma entrada específica:

function isCompatible(item) {
  // In real life you most likely have more complex rules here
  return ['Chromium', 'Google Chrome', 'NewBrowser'].includes(item.brand);
}
if (navigator.userAgentData.brands.some(isCompatible)) {
  // browser reports as compatible
}

Se você precisar de um dos valores de user agent mais detalhados e de alta entropia, é necessário especificá-lo e verificar o resultado no Promise retornado:

navigator.userAgentData.getHighEntropyValues(['model'])
  .then(ua => {
    // requested hints available as attributes
    const model = ua.model
  });

Você também pode usar essa estratégia se quiser migrar da do lado do servidor para o do cliente. A API JavaScript não exigem acesso a cabeçalhos de solicitação HTTP, de modo que os valores de user agent podem ser solicitados em em qualquer ponto.

Estratégia: cabeçalho estático do lado do servidor

Se você estiver usando o cabeçalho de solicitação User-Agent no servidor e suas necessidades para esses dados sejam relativamente consistentes em todo o site, então será possível especificar as dicas de cliente desejadas como um conjunto estático nas suas respostas. Esta é uma abordagem relativamente simples, já que você geralmente só precisa configurá-la de uma o local. Por exemplo, ele pode estar na configuração do servidor da Web se você já adicione os cabeçalhos lá, sua configuração de hospedagem ou configuração de nível superior do ou plataforma que você usa para seu site.

Considere essa estratégia se você estiver transformando ou personalizando as respostas exibido com base nos dados do user agent.

Navegadores ou outros clientes podem optar por fornecer diferentes dicas padrão, portanto é prática recomendada para especificar tudo o que você precisa, mesmo que geralmente seja fornecido por padrão.

Por exemplo, os padrões atuais do Chrome seriam representados como:

⬇️ Cabeçalhos de resposta

Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA

Se você também quiser receber o modelo do dispositivo nas respostas, enviar:

⬇️ Cabeçalhos de resposta

Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA

Ao processar isso no servidor, primeiro você deve verificar se o estado O cabeçalho Sec-CH-UA foi enviado e substituído pelo cabeçalho User-Agent a análise se não estiver disponível.

Estratégia: delegar dicas a solicitações de diferentes origens

Se você solicitar sub-recursos entre sites ou origens que exigem Dicas de cliente HTTP do user agent enviadas nas solicitações. Depois, você vai precisar especificar explicitamente as dicas desejadas usando uma política de permissões.

Por exemplo, digamos que https://blog.site hospede recursos em https://cdn.site, que pode retornar recursos otimizados para um dispositivo específico. https://blog.site pode pedir a dica Sec-CH-UA-Model, mas precisa o delegue explicitamente para https://cdn.site usando o Permissions-Policy cabeçalho. A lista de dicas controladas pela política está disponível em Dicas de clientes Infraestrutura rascunho

⬇️ Resposta de blog.site delegando a dica

Accept-CH: Sec-CH-UA-Model
Permissions-Policy: ch-ua-model=(self "https://cdn.site")

⬆️ A solicitação de sub-recursos em cdn.site inclui a dica delegada

Sec-CH-UA-Model: "Pixel 5"

Você pode especificar várias dicas para diversas origens, e não apenas no intervalo ch-ua:

⬇️ Resposta de blog.site delegando várias dicas a várias origens

Accept-CH: Sec-CH-UA-Model, DPR
Permissions-Policy: ch-ua-model=(self "https://cdn.site"),
                    ch-dpr=(self "https://cdn.site" "https://img.site")

Estratégia: delegar dicas a iframes

Os iframes de origem cruzada funcionam de maneira semelhante aos recursos de origem cruzada, mas é especifique as dicas que você quer delegar no atributo allow.

⬇️ Resposta de blog.site

Accept-CH: Sec-CH-UA-Model

↪️ HTML de blog.site

<iframe src="https://widget.site" allow="ch-ua-model"></iframe>

⬆️ Solicitação para widget.site

Sec-CH-UA-Model: "Pixel 5"

O atributo allow no iframe vai substituir qualquer cabeçalho Accept-CH que widget.site pode enviar a si mesmo, portanto, verifique se você especificou tudo o que site com iframe.

Estratégia: dicas dinâmicas do lado do servidor

Se você precisa de uma seleção maior em partes específicas da jornada do usuário mais dicas do que no restante do site, você pode solicitar essas dicas sob demanda, e não estaticamente em todo o site. Isso é mais complexo para gerenciar, mas se você já definiu cabeçalhos diferentes por rota, isso pode ser viável.

É importante lembrar que cada instância do Accept-CH vai substituir o conjunto atual. Portanto, se você for dinamicamente definindo o cabeçalho, cada página deve solicitar o conjunto completo de dicas necessárias.

Por exemplo, você pode ter uma seção no seu site em que quer fornecer ícones e controles que correspondem ao sistema operacional do usuário. Para isso, é possível extrair também Sec-CH-UA-Platform-Version para veicular anúncios sub-recursos.

⬇️ Cabeçalhos de resposta para /blog

Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA

⬇️ Cabeçalhos de resposta para /app

Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA

Estratégia: dicas do lado do servidor necessárias na primeira solicitação

Pode haver casos em que você precisa de mais do que o conjunto padrão de dicas no na primeira solicitação, mas isso provavelmente será raro. Portanto, analisamos o raciocínio.

A primeira solicitação realmente significa a primeira solicitação de nível superior para essa origem na sessão de navegação. O conjunto padrão de dicas inclui o navegador nome com a versão principal, a plataforma e o indicador de celular. Então, a pergunta você precisa de dados estendidos no carregamento inicial da página?

Para obter dicas adicionais na primeira solicitação, há duas opções. Primeiro, você pode use o cabeçalho Critical-CH. Ele tem o mesmo formato de Accept-CH. mas informa ao navegador que ele deve repetir a solicitação imediatamente se a primeira uma foi enviada sem a dica crítica.

⬆️ Solicitação inicial

[With default headers]

⬇️ Cabeçalhos de resposta

Accept-CH: Sec-CH-UA-Model
Critical-CH: Sec-CH-UA-Model

🔃 O navegador tenta novamente a solicitação inicial com o cabeçalho extra

[With default headers + …]
Sec-CH-UA-Model: Pixel 5

Isso acarretará a sobrecarga da nova tentativa na primeira solicitação, mas o o custo de implementação é relativamente baixo. Envie o cabeçalho extra e o navegador que fará o resto.

Para situações em que você realmente precisa de dicas adicionais sobre os primeiro carregamento de página, o tópico Confiabilidade de dicas do cliente proposta é definir uma rota para especificar dicas nas configurações de conexão. Isso usa o protocolo de camada de aplicativo Extensão Settings(ALPS) para o TLS 1.3 para permitir a passagem antecipada de dicas sobre conexões HTTP/2 e HTTP/3. Isso ainda está em estágio inicial, mas se você gerenciar ativamente sua própria TLS e configurações de conexão, esse é o momento ideal para contribuir.

Estratégia: suporte legado

Talvez você tenha um código legado ou de terceiros no seu site que dependa navigator.userAgent, incluindo as partes da string do user agent que serão reduzidos. A longo prazo, você deve planejar mudar para o equivalente navigator.userAgentData, mas há uma solução provisória.

O retrofill do UA-CH é um pequeno que permite substituir navigator.userAgent por uma nova string criado a partir dos valores navigator.userAgentData solicitados.

Por exemplo, o código gera uma string user agent que também inclui o "modelo", Dica:

import { overrideUserAgentUsingClientHints } from './uach-retrofill.js';
overrideUserAgentUsingClientHints(['model'])
  .then(() => { console.log(navigator.userAgent); });

A string resultante mostraria o modelo Pixel 5, mas ainda mostraria o número 92.0.0.0 como a dica uaFullVersion não foi solicitada:

Mozilla/5.0 (Linux; Android 10.0; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.0.0 Mobile Safari/537.36

Suporte adicional

Se essas estratégias não abordarem seu caso de uso, inicie uma Discussão no privacy-sandbox-dev-support repositório para analisarmos o problema juntos.

Foto de Ricardo Rocha no Unsplash