Estrategias para migrar tu sitio de depender de la cadena de 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 pasivas significativa en los navegadores, además de ser difícil de procesar. Sin embargo, hay todo tipo de motivos válidos para recopilar y procesar datos del usuario-agente, por lo que lo que se necesita es una ruta hacia una mejor solución. Las sugerencias del cliente del usuario-agente proporcionan una forma explícita de declarar tu necesidad de datos del usuario-agente y métodos para mostrar los datos en un formato fácil de usar.
En este artículo, se explica cómo auditar tu acceso a los datos de usuario-agente y migrar el uso de la cadena de usuario-agente a las Client Hints de usuario-agente.
Auditoría de la recopilación y el uso de datos de 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 datos de usuario-agente o dónde, considera buscar en tu código de frontend el uso de navigator.userAgent
y en tu código de backend el uso del encabezado HTTP User-Agent
. También debes verificar tu código de frontend para comprobar si usas funciones que ya están obsoletas, como navigator.platform
y navigator.appVersion
.
Desde un punto de vista funcional, piensa en cualquier parte de tu código en la que grabes o proceses lo siguiente:
- Nombre o versión del navegador
- Nombre o versión del sistema operativo
- Marca o modelo del dispositivo
- Tipo, arquitectura o cantidad de bits de la CPU (por ejemplo, 64 bits)
También es probable que estés usando 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 del usuario-agente?
El conjunto predeterminado de sugerencias de clientes de usuario-agente incluye lo siguiente:
Sec-CH-UA
: nombre del navegador y versión principal o significativaSec-CH-UA-Mobile
: Es un valor booleano que indica un dispositivo móvil.Sec-CH-UA-Platform
: Es el nombre del sistema operativo.- Ten en cuenta que esto se actualizó en la especificación y se reflejará en Chrome y otros navegadores basados en Chromium en breve.
La versión reducida de la cadena de usuario-agente que se propone también retendrá esta información básica de forma retrocompatible. Por ejemplo, en lugar de Chrome/90.0.4430.85
, la cadena incluiría Chrome/90.0.0.0
.
Si solo verificas la cadena de 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 las Client Hints de usuario-agente, 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 preferir navigator.userAgentData
antes de recurrir al análisis de la cadena de usuario-agente.
if (navigator.userAgentData) {
// use new hints
} else {
// fall back to user-agent string parsing
}
Si quieres verificar si se trata de un dispositivo móvil o una computadora, 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 de 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 los valores del usuario-agente se pueden solicitar en cualquier momento.
Estrategia: Encabezado estático del servidor
Si usas el encabezado de solicitud User-Agent
en el servidor y tus necesidades para 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 debes configurarlo en una ubicación. Por ejemplo, puede estar en la configuración de tu servidor web si ya
agregas encabezados allí, la configuración de tu host 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 que se entregan en función de los datos del usuario-agente.
Los navegadores y otros clientes pueden proporcionar diferentes sugerencias predeterminadas, por lo que es una práctica recomendada especificar todo lo que necesitas, incluso si se proporciona de forma predeterminada.
Por ejemplo, los valores predeterminados actuales de Chrome se representarían de la siguiente manera:
⬇️ Encabezados de respuesta
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA
Si también quieres 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 lo proceses del lado del 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 de sitio cruzado que requieren que se envíen Client Hints de usuario-agente en sus solicitudes, deberás especificar explícitamente las sugerencias deseadas con una Política de Permisos.
Por ejemplo, supongamos que https://blog.site
aloja recursos en https://cdn.site
, que puede 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 del rango ch-ua
:
⬇️ Respuesta de blog.site
que delega varios indicadores 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: Delegación de 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
en el iframe anulará cualquier encabezado Accept-CH
que widget.site
pueda enviarse, por lo que debes asegurarte de haber especificado todo lo que necesitará el sitio del 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, puedes tener una sección en tu sitio en la que deseas proporcionar íconos y controles que coincidan con el sistema operativo del usuario. Para ello, es posible que desees extraer Sec-CH-UA-Platform-Version
para entregar los 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 que el conjunto predeterminado de sugerencias en la primera solicitud. Sin embargo, es probable que esto sea poco frecuente, así que asegúrate de revisar el razonamiento.
La primera solicitud realmente significa 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. Por lo tanto, la pregunta que debes hacerte 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 hará el resto.
En situaciones en las que realmente necesitas sugerencias adicionales en la primera carga de página, la propuesta de confiabilidad de las sugerencias del cliente establece una ruta para especificar sugerencias en la configuración a nivel de la conexión. Para ello, se usa la extensión Protocolo de configuración de la capa de aplicación(ALPS) a TLS 1.3 para habilitar este pase anticipado de sugerencias en las conexiones HTTP/2 y HTTP/3. Esta función aún se encuentra en una etapa muy inicial, 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 dependa de navigator.userAgent
, incluidas partes de la cadena de usuario-agente que se reducirán. A largo plazo, debes planificar el cambio a las llamadas navigator.userAgentData
equivalentes, pero hay una solución provisional.
UA-CH retrofill es una biblioteca pequeña que te permite reemplazar navigator.userAgent
por una cadena nueva creada a partir de los valores de navigator.userAgentData
solicitados.
Por ejemplo, este código generará una cadena de usuario-agente que, además, incluirá la sugerencia “modelo”:
import { overrideUserAgentUsingClientHints } from './uach-retrofill.js';
overrideUserAgentUsingClientHints(['model'])
.then(() => { console.log(navigator.userAgent); });
La cadena resultante mostraría el modelo Pixel 5
, pero aún mostraría 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 abarcan tu caso de uso, inicia una discusión en el repositorio de privacy-sandbox-dev-support para que podamos analizar tu problema juntos.
Foto de Ricardo Rocha en Unsplash