Migrer vers les indicateurs client user-agent

Stratégies pour migrer votre site en remplaçant la chaîne user-agent par les nouveaux indicateurs client user-agent.

La chaîne User-Agent est une surface de fingerprinting passif importante dans les navigateurs, en plus d'être difficile à traiter. Cependant, il existe toutes sortes de raisons valables pour collecter et traiter les données des user-agents. Il est donc nécessaire de trouver une meilleure solution. Les hints client user-agent permettent de déclarer explicitement que vous avez besoin de données user-agent et de méthodes pour renvoyer les données dans un format facile à utiliser.

Cet article vous explique comment vérifier votre accès aux données des user-agents et comment migrer l'utilisation de la chaîne user-agent vers les hints client user-agent.

Auditer la collecte et l'utilisation des données des user-agents

Comme pour toute forme de collecte de données, vous devez toujours comprendre pourquoi vous les collectez. Que vous preniez ou non une mesure, la première étape consiste à comprendre où et pourquoi vous utilisez les données user-agent.

Si vous ne savez pas si ou où les données user-agent sont utilisées, envisagez d'effectuer une recherche dans votre code frontal pour l'utilisation de navigator.userAgent et dans votre code backend pour l'utilisation de l'en-tête HTTP User-Agent. Vous devez également vérifier que votre code d'interface utilise des fonctionnalités déjà obsolètes, telles que navigator.platform et navigator.appVersion.

D'un point de vue fonctionnel, pensez à toutes les parties du code où vous enregistrez ou traitez:

  • Nom ou version du navigateur
  • Nom ou version du système d'exploitation
  • Marque ou modèle de l'appareil
  • Type de processeur, architecture ou débit (par exemple, 64 bits)

Il est également probable que vous utilisiez une bibliothèque ou un service tiers pour traiter le user-agent. Dans ce cas, vérifiez si la mise à jour est en cours pour prendre en charge les hints client user-agent.

Utilisez-vous uniquement des données user-agent de base ?

L'ensemble par défaut d'indicateurs client User-Agent comprend les éléments suivants:

  • Sec-CH-UA: nom du navigateur et version majeure/significative
  • Sec-CH-UA-Mobile: valeur booléenne indiquant un appareil mobile
  • Sec-CH-UA-Platform: nom du système d'exploitation
    • Notez que cette fonctionnalité a été mise à jour dans les spécifications et qu'elle sera remplie bientôt dans Chrome et d'autres navigateurs basés sur Chromium.

La version réduite de la chaîne de user-agent proposée conservera également ces informations de base de manière rétrocompatible. Par exemple, la chaîne inclut Chrome/90.0.0.0 au lieu de Chrome/90.0.4430.85.

Si vous ne vérifiez que la chaîne du user-agent pour le nom du navigateur, la version majeure ou le système d'exploitation, votre code continuera de fonctionner, mais vous risquez de voir des avertissements d'abandon.

Bien que vous puissiez et devriez migrer vers les hints client user-agent, d'anciennes contraintes de code ou de ressources peuvent vous empêcher de le faire. La réduction des informations dans la chaîne du user-agent par cette méthode rétrocompatible est destinée à garantir que, bien que le code existant reçoive des informations moins détaillées, il conserve ses fonctionnalités de base.

Stratégie: API JavaScript côté client à la demande

Si vous utilisez actuellement navigator.userAgent, vous devez passer à navigator.userAgentData avant de revenir à l'analyse de la chaîne user-agent.

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

Si vous recherchez un appareil mobile ou un ordinateur, utilisez la valeur booléenne mobile:

const isMobile = navigator.userAgentData.mobile;

userAgentData.brands est un tableau d'objets avec les propriétés brand et version, dans lequel le navigateur peut répertorier sa compatibilité avec ces marques. Vous pouvez y accéder directement en tant que tableau ou utiliser un appel some() pour vérifier si une entrée spécifique est présente:

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 vous avez besoin de l'une des valeurs de user-agent les plus détaillées et à entropie élevée, vous devez la spécifier et rechercher le résultat dans le Promise renvoyé:

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

Vous pouvez également utiliser cette stratégie si vous souhaitez passer du traitement côté serveur au traitement côté client. L'API JavaScript ne nécessite pas d'accès aux en-têtes de requêtes HTTP. Les valeurs de user-agent peuvent donc être demandées à tout moment.

Stratégie: en-tête statique côté serveur

Si vous utilisez l'en-tête de requête User-Agent sur le serveur et que vos besoins concernant ces données sont relativement cohérents sur l'ensemble de votre site, vous pouvez spécifier les indications de client souhaitées sous la forme d'un ensemble statique dans vos réponses. Il s'agit d'une approche relativement simple, car vous n'avez généralement besoin de la configurer que dans un seul emplacement. Par exemple, ce peut être dans la configuration de votre serveur Web si vous y ajoutez déjà des en-têtes, votre configuration d'hébergement, ou la configuration de premier niveau du framework ou de la plate-forme que vous utilisez pour votre site.

Envisagez cette stratégie si vous transformez ou personnalisez les réponses diffusées en fonction des données du user-agent.

Les navigateurs ou d'autres clients peuvent choisir de fournir différentes suggestions par défaut. Il est donc recommandé de spécifier tout ce dont vous avez besoin, même s'ils sont généralement fournis par défaut.

Par exemple, les valeurs par défaut actuelles de Chrome sont représentées comme suit:

⬇️ En-têtes de réponse

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

Si vous souhaitez également recevoir le modèle d'appareil dans les réponses, envoyez:

⬇️ En-têtes de réponse

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

Lors du traitement côté serveur, vous devez d'abord vérifier si l'en-tête Sec-CH-UA souhaité a été envoyé, puis revenir à l'analyse de l'en-tête User-Agent s'il n'est pas disponible.

Stratégie: déléguer des indices aux demandes d'origine croisée

Si vous demandez des sous-ressources multi-origines ou intersites nécessitant l'envoi de hints client user-agent dans leurs requêtes, vous devez spécifier explicitement les indications souhaitées à l'aide d'une règle d'autorisation.

Par exemple, supposons que https://blog.site héberge des ressources sur https://cdn.site, qui peuvent renvoyer des ressources optimisées pour un appareil spécifique. https://blog.site peut demander l'indice Sec-CH-UA-Model, mais doit le déléguer explicitement à https://cdn.site à l'aide de l'en-tête Permissions-Policy. La liste des suggestions contrôlées par des règles est disponible dans le brouillon d'infrastructure d'indicateurs clients.

⬇️ Réponse de blog.site qui délègue l'indice

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

⩍️ Les demandes de sous-ressources sur cdn.site incluent l'indice délégué

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

Vous pouvez spécifier plusieurs suggestions pour plusieurs origines, et pas seulement à partir de la plage ch-ua:

⬇️ Réponse de blog.site qui délègue plusieurs indices à plusieurs origines

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

Stratégie: déléguer des suggestions à des cadres iFrame

Les iFrames multi-origines fonctionnent de la même manière que les ressources multi-origines, à la différence que vous spécifiez les optimisations que vous souhaitez déléguer dans l'attribut allow.

⬇️ Réponse de blog.site

Accept-CH: Sec-CH-UA-Model

↪️ HTML pour blog.site

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

📈️ Demande à widget.site

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

L'attribut allow de l'iFrame remplace tout en-tête Accept-CH que widget.site est susceptible d'envoyer lui-même. Assurez-vous donc d'avoir spécifié tout ce dont le site iFrame aura besoin.

Stratégie: conseils dynamiques côté serveur

Si vous avez besoin d'une plus grande sélection d'indices pour certaines parties du parcours utilisateur, vous pouvez choisir de les demander à la demande plutôt que de manière statique sur l'ensemble du site. Cette opération est plus complexe à gérer, mais si vous avez déjà défini des en-têtes différents pour chaque route, c'est peut-être faisable.

N'oubliez pas que chaque instance de l'en-tête Accept-CH écrasera efficacement l'ensemble existant. Ainsi, si vous définissez l'en-tête de manière dynamique, chaque page doit demander l'ensemble complet d'indicateurs requis.

Par exemple, vous pouvez avoir une section de votre site dans laquelle vous souhaitez fournir des icônes et des commandes correspondant au système d'exploitation de l'utilisateur. Pour ce faire, vous pouvez également extraire Sec-CH-UA-Platform-Version afin de diffuser les sous-ressources appropriées.

⬇️ En-têtes de réponse pour /blog

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

⬇️ En-têtes de réponse pour /app

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

Stratégie: conseils côté serveur requis lors de la première demande

Vous aurez peut-être besoin d'autres éléments que l'ensemble d'indications par défaut lors de la toute première requête. Toutefois, cela risque d'être rare. Assurez-vous donc d'avoir examiné le raisonnement.

La première requête correspond en fait à la toute première requête de niveau supérieur pour cette origine envoyée dans cette session de navigation. L'ensemble d'indicateurs par défaut comprend le nom du navigateur avec la version principale, la plate-forme et l'indicateur de mobile. La question à se poser est la suivante : avez-vous besoin de données étendues lors du chargement initial de la page ?

Pour obtenir des conseils supplémentaires sur la première requête, deux options s'offrent à vous. Tout d'abord, vous pouvez utiliser l'en-tête Critical-CH. Cette méthode utilise le même format que Accept-CH, mais indique au navigateur qu'il doit immédiatement relancer la requête si la première a été envoyée sans l'indice critique.

⧖️ Demande initiale

[With default headers]

⬇️ En-têtes de réponse

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

🔃 Le navigateur relance la requête initiale avec l'en-tête supplémentaire

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

Cela entraîne des frais généraux liés à la nouvelle tentative lors de la toute première requête, mais le coût d'implémentation est relativement faible. Envoyez l'en-tête supplémentaire et le navigateur se chargera du reste.

Dans les cas où vous avez vraiment besoin de conseils supplémentaires au tout premier chargement de la page, la proposition de fiabilité des indications client prévoit un chemin pour spécifier des indications dans les paramètres de niveau de connexion. Elle utilise l'extension ALPS(Application-Layer Protocol Settings) dans TLS 1.3 pour permettre le transfert anticipé d'indications sur les connexions HTTP/2 et HTTP/3. Ce n'est qu'un début, mais si vous gérez activement vos propres paramètres TLS et de connexion, c'est le moment idéal pour apporter votre contribution.

Stratégie: compatibilité avec les anciennes versions

Il est possible que votre site contienne du code ancien ou tiers qui dépend de navigator.userAgent, y compris des parties de la chaîne user-agent qui seront réduites. À long terme, vous devez prévoir de passer aux appels navigator.userAgentData équivalents, mais il existe une solution provisoire.

La retrofill UA-CH est une petite bibliothèque qui vous permet de remplacer navigator.userAgent par une nouvelle chaîne créée à partir des valeurs navigator.userAgentData demandées.

Par exemple, ce code génère une chaîne de user-agent qui inclut également l'indice "model" :

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

La chaîne obtenue affiche le modèle Pixel 5, mais affiche toujours le 92.0.0.0 réduit, car la suggestion uaFullVersion n'a pas été demandée:

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

Assistance supplémentaire

Si ces stratégies ne correspondent pas à votre cas d'utilisation, veuillez démarrer une discussion dans le dépôt privacy-sandbox-dev-support et nous pourrons examiner votre problème ensemble.

Photo par Ricardo Rocha sur Unsplash