Migra a Client Hints de usuario-agente

Estrategias para migrar tu sitio de depender de la string usuario-agente a las nuevas Sugerencias de clientes de usuario-agente.

La cadena de usuario-agente es una superficie de creación de huellas digitales pasiva en navegadores que también es difícil de procesar. Sin embargo, existen muchos tipos de motivos válidos para recopilar y procesar los datos del usuario-agente, por lo que lo que se necesita es una ruta a una mejor solución. Las Sugerencias de clientes de usuario-agente proporcionan una forma explícita de declarar tu necesidad de datos de usuario-agente y métodos para mostrarlos en un formato fácil de usar.

En este artículo, aprenderás a auditar tu acceso a los datos de usuario-agente y a migrar el uso de cadenas de usuario-agente a User-Agent Client Hints.

Audita la recopilación y el uso de los datos del usuario-agente

Al igual que con cualquier forma de recopilación de datos, siempre debes comprender por qué los recopilas. El primer paso, independientemente de si tomarás alguna medida o no, es comprender dónde y por qué usas los datos de usuario-agente.

Si no sabes si se usan los datos del usuario-agente ni dónde se usan, considera buscar en el código de frontend para usar navigator.userAgent y el código de backend para usar el encabezado HTTP User-Agent. También debes verificar el código de frontend para verificar el uso de funciones ya obsoletas, como navigator.platform y navigator.appVersion.

Desde un punto de vista funcional, piensa en cualquier lugar de tu código en el que estés grabando o procesando:

  • Nombre o versión del navegador
  • Nombre o versión del sistema operativo
  • Marca o modelo del dispositivo
  • Tipo de CPU, arquitectura o valor de bits (por ejemplo, 64 bits)

También es probable que uses una biblioteca o un servicio de terceros para procesar el usuario-agente. En este caso, verifica si se están actualizando para admitir Client Hints de usuario-agente.

¿Solo usas datos básicos de usuario-agente?

El conjunto predeterminado de Client Hints de Usuario-Agente incluye lo siguiente:

  • Sec-CH-UA: nombre del navegador y versión principal o significativa
  • Sec-CH-UA-Mobile: valor booleano que indica un dispositivo móvil
  • Sec-CH-UA-Platform: El nombre del sistema operativo

La versión reducida de la string de usuario-agente que se propone también conservará esta información básica de una manera retrocompatible. Por ejemplo, en lugar de Chrome/90.0.4430.85, la cadena incluiría Chrome/90.0.0.0.

Si solo verificas la string usuario-agente para el nombre del navegador, la versión principal o el sistema operativo, tu código seguirá funcionando, aunque es probable que veas advertencias de baja.

Si bien puedes y debes migrar a User-Agent Client Hints, es posible que tengas restricciones de código o recursos heredados que lo impidan. La reducción de información en la string usuario-agente de esta manera retrocompatible tiene el objetivo de garantizar que, si bien el código existente recibirá información menos detallada, conserve la funcionalidad básica.

Estrategia: API de JavaScript del cliente a pedido

Si actualmente usas navigator.userAgent, debes hacer la transición a preferir navigator.userAgentData antes de volver a analizar la string usuario-agente.

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

Si estás verificando dispositivos móviles o computadoras de escritorio, usa el valor booleano mobile:

const isMobile = navigator.userAgentData.mobile;

userAgentData.brands es un array de objetos con propiedades brand y version en el que el navegador puede enumerar su compatibilidad con esas marcas. Puedes acceder a él directamente como un array o usar una llamada a some() para verificar si hay una entrada específica presente:

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
}

Si necesitas uno de los valores de usuario-agente más detallados y con alta entropía, deberás especificarlo y verificar el resultado en el Promise que se muestra:

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

También puedes usar esta estrategia si deseas pasar del procesamiento del servidor al procesamiento del cliente. La API de JavaScript no requiere acceso a los encabezados de solicitud HTTP, por lo que se pueden solicitar valores de usuario-agente en cualquier momento.

Estrategia: Encabezado estático del servidor

Si usas el encabezado de solicitud User-Agent en el servidor y tus necesidades de esos datos son relativamente coherentes en todo el sitio, puedes especificar las sugerencias de cliente deseadas como un conjunto estático en tus respuestas. Este es un enfoque relativamente simple, ya que, por lo general, solo necesitas configurarlo en una ubicación. Por ejemplo, puede estar en la configuración de tu servidor web si ya agregaste encabezados allí, tu configuración de hosting o la configuración de nivel superior del framework o la plataforma que usas para tu sitio.

Considera esta estrategia si transformas o personalizas las respuestas entregadas según los datos del usuario-agente.

Los navegadores y otros clientes pueden optar por proporcionar diferentes sugerencias predeterminadas, por lo que se recomienda especificar todo lo que necesitas, incluso si se proporciona de forma predeterminada.

Por ejemplo, la configuración predeterminada actual para Chrome se representaría de la siguiente manera:

⬇️ Encabezados de respuesta

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

Si también deseas recibir el modelo del dispositivo en las respuestas, debes enviar lo siguiente:

⬇️ Encabezados de respuesta

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

Cuando procesas esto en el servidor, primero debes verificar si se envió el encabezado Sec-CH-UA deseado y, luego, recurrir al análisis del encabezado User-Agent si no está disponible.

Estrategia: Delegación de sugerencias a solicitudes de origen cruzado

Si solicitas subrecursos de origen cruzado o entre sitios que requieren que se envíen las Sugerencias de clientes de usuario-agente en sus solicitudes, deberás especificar de forma explícita las sugerencias deseadas con una política de permisos.

Por ejemplo, supongamos que https://blog.site aloja recursos en https://cdn.site, que pueden mostrar recursos optimizados para un dispositivo específico. https://blog.site puede solicitar la sugerencia Sec-CH-UA-Model, pero necesita delegarla explícitamente a https://cdn.site con el encabezado Permissions-Policy. La lista de sugerencias controladas por políticas está disponible en el borrador de infraestructura de sugerencias de clientes.

⬇️ Respuesta de blog.site delegando la pista

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

⬆️ La solicitud a los subrecursos de cdn.site incluye la sugerencia delegada

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

Puedes especificar varias sugerencias para varios orígenes, y no solo desde el rango ch-ua:

🔍️ Respuesta de blog.site en la que se delegan varias sugerencias a varios orígenes

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")

Estrategia: Delega sugerencias a iframes

Los iframes de origen cruzado funcionan de manera similar a los recursos de origen cruzado, pero debes especificar las sugerencias que deseas delegar en el atributo allow.

⬇️ Respuesta de blog.site

Accept-CH: Sec-CH-UA-Model

↪️ HTML para blog.site

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

⬆️ Solicitud para widget.site

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

El atributo allow del iframe anulará cualquier encabezado Accept-CH que widget.site pueda enviarse a sí mismo, así que asegúrate de haber especificado todo lo que necesitará el sitio iframe.

Estrategia: Sugerencias dinámicas del servidor

Si tienes partes específicas del recorrido del usuario en las que necesitas una selección más grande de sugerencias que en el resto del sitio, puedes optar por solicitar esas sugerencias a pedido en lugar de hacerlo de manera estática en todo el sitio. Esto es más complejo de administrar, pero si ya configuraste diferentes encabezados por ruta, puede ser factible.

Lo importante que debes recordar aquí es que cada instancia del encabezado Accept-CH reemplazará de manera efectiva el conjunto existente. Por lo tanto, si configuras el encabezado de forma dinámica, cada página debe solicitar el conjunto completo de sugerencias requeridas.

Por ejemplo, es posible que tengas una sección en tu sitio en la que quieras proporcionar íconos y controles que coincidan con el sistema operativo del usuario. Para esto, te recomendamos extraer Sec-CH-UA-Platform-Version adicionalmente a fin de entregar subrecursos adecuados.

⬇️ Encabezados de respuesta para /blog

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

⬇️ Encabezados de respuesta para /app

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

Estrategia: Se requieren sugerencias del servidor en la primera solicitud

Puede haber casos en los que necesites más sugerencias que el conjunto predeterminado de sugerencias en la primera solicitud. Sin embargo, es probable que esto sea poco común, así que asegúrate de haber revisado el razonamiento.

La primera solicitud en realidad se refiere a la primera solicitud de nivel superior para ese origen que se envió en esa sesión de navegación. El conjunto predeterminado de sugerencias incluye el nombre del navegador con la versión principal, la plataforma y el indicador de dispositivo móvil. Entonces, la pregunta que debes hacer es si necesitas datos extendidos en la carga inicial de la página.

Para obtener sugerencias adicionales sobre la primera solicitud, hay dos opciones. Primero, puedes usar el encabezado Critical-CH. Toma el mismo formato que Accept-CH, pero le indica al navegador que debe reintentar la solicitud de inmediato si la primera se envió sin la sugerencia crítica.

⬆️ Solicitud inicial

[With default headers]

⬇️ Encabezados de respuesta

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

🔃 El navegador vuelve a intentar la solicitud inicial con el encabezado adicional

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

Esto generará la sobrecarga del reintento en la primera solicitud, pero el costo de implementación es relativamente bajo. Envía el encabezado adicional y el navegador se encargará del resto.

En situaciones en las que realmente necesitas sugerencias adicionales en la primera carga de la página, la propuesta de confiabilidad de Sugerencias de clientes diseña una ruta para especificar sugerencias en la configuración del nivel de conexión. Esto hace que se use la extensión de Configuración del protocolo de la capa de la aplicación(ALPS) a TLS 1.3 para habilitar este pase anticipado de sugerencias en las conexiones HTTP/2 y HTTP/3. Esto aún se encuentra en una etapa muy temprana, pero si administras de forma activa tu propia configuración de TLS y conexión, este es un momento ideal para contribuir.

Estrategia: Asistencia heredada

Es posible que tengas código heredado o de terceros en tu sitio que depende de navigator.userAgent, incluidas las partes de la string del usuario-agente que se reducirán. A largo plazo, deberías planificar pasar a las llamadas equivalentes de navigator.userAgentData, pero existe una solución provisional.

El reverso de UA-CH es una biblioteca pequeña que te permite reemplazar navigator.userAgent por una string nueva compilada a partir de los valores de navigator.userAgentData solicitados.

Por ejemplo, este código generará una string usuario-agente que, además, incluye la sugerencia del “modelo”:

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

La string resultante mostraría el modelo Pixel 5, pero aún muestra el 92.0.0.0 reducido, ya que no se solicitó la sugerencia uaFullVersion:

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

Más asistencia

Si estas estrategias no cubren tu caso de uso, inicia un debate en el repositorio de privacy-sandbox-dev-support para que podamos analizar tu problema juntos.

Foto de Ricardo Rocha en Unsplash