Przeprowadź migrację do wskazówek dotyczących klienta użytkownika

Strategie migracji witryny z używania ciągu user-agent na nowe wskazówki dotyczące klienta użytkownika.

Ciąg znaków User-Agent to ważna powierzchnia biernego odcisku palca w przeglądarkach, która jest trudna do przetworzenia. Istnieją jednak różne prawidłowe powody gromadzenia i przetwarzania danych użytkownika, więc potrzebna jest droga do lepszego rozwiązania. Wskazówki klienta User-Agent zapewniają zarówno wyraźny sposób zadeklarowania potrzebnych danych User-Agent, jak i metody zwracania tych danych w łatwym w użyciu formacie.

Z tego artykułu dowiesz się, jak sprawdzić dostęp do danych dotyczących klienta użytkownika i jak przenieść użycie ciągu klienta użytkownika do wskazówek dotyczących klienta użytkownika.

Kontrola zbierania i wykorzystywania danych użytkownika

Podobnie jak w przypadku każdej formy gromadzenia danych, musisz zawsze wiedzieć, dlaczego to robisz. Pierwszym krokiem, niezależnie od tego, czy podejmiesz jakieś działania, jest ustalenie, gdzie i po co używasz danych użytkownika.

Jeśli nie wiesz, czy i gdzie są używane dane klienta użytkownika, poszukaj w kodzie front-endu informacji o użyciu navigator.userAgent, a w kodzie back-endu – o użyciu nagłówka HTTP User-Agent. Sprawdź też kod front-endu pod kątem używania funkcji, które zostały wycofane, takich jak navigator.platformnavigator.appVersion.

Z funkcjonalnego punktu widzenia zastanów się, gdzie w kodzie odbywa się nagrywanie lub przetwarzanie:

  • Nazwa lub wersja przeglądarki
  • Nazwa lub wersja systemu operacyjnego
  • Marka lub model urządzenia
  • typ procesora, architektura lub liczba bitów (np. 64-bitowa);

Prawdopodobnie do przetwarzania użytkownika używasz biblioteki lub usługi innej firmy. W takim przypadku sprawdź, czy aktualizują się do obsługi wskazówek dotyczących klienta użytkownika.

Czy używasz tylko podstawowych danych użytkownika?

Domyślny zestaw wskazówek dotyczących klienta użytkownika obejmuje:

  • Sec-CH-UA: nazwa przeglądarki i główna wersja
  • Sec-CH-UA-Mobile: wartość logiczna wskazująca urządzenie mobilne
  • Sec-CH-UA-Platform: nazwa systemu operacyjnego

Proponowana wersja uproszczona ciągu znaków user-agent zachowa te podstawowe informacje w sposób zgodny ze starszymi wersjami. Na przykład zamiast Chrome/90.0.4430.85 ciąg znaków zawiera Chrome/90.0.0.0.

Jeśli sprawdzasz tylko ciąg znaków User-Agent pod kątem nazwy przeglądarki, wersji głównej lub systemu operacyjnego, Twój kod będzie nadal działać, ale prawdopodobnie zobaczysz ostrzeżenia o wycofaniu.

Chociaż możesz i powinieneś przejść na wskazówki dotyczące klienta użytkownika, możesz mieć starszy kod lub ograniczenia zasobów, które uniemożliwiają Ci to. Zmniejszenie ilości informacji w ciągu user-agenta w taki sposób, aby zachować zgodność wsteczną, ma na celu zapewnienie, że chociaż istniejący kod będzie otrzymywać mniej szczegółowe informacje, to zachowa podstawowe funkcje.

Strategia: interfejs JavaScript API po stronie klienta na żądanie

Jeśli obecnie używasz parametru navigator.userAgent, przed przejściem na parsowanie ciągu user-agent powinieneś preferować parametr navigator.userAgentData.

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

Jeśli sprawdzasz wersję mobilną lub komputerową, użyj wartości logicznej mobile:

const isMobile = navigator.userAgentData.mobile;

userAgentData.brands to tablica obiektów z właściwościami brandversion, w których przeglądarka może podać informacje o zgodności z tymi markami. Możesz uzyskać do niego dostęp bezpośrednio jako tablicy lub użyć wywołania some(), aby sprawdzić, czy występuje w niej określony wpis:

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
}

Jeśli potrzebujesz bardziej szczegółowej wartości identyfikatora użytkownika o wysokiej entropii, musisz ją podać i sprawdzić wynik zwrócony w wartości Promise:

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

Możesz też użyć tej strategii, jeśli chcesz przejść z przetwarzania po stronie serwera na przetwarzanie po stronie klienta. Interfejs JavaScript API nie wymaga dostępu do nagłówków żądań HTTP, więc wartości klienta użytkownika można poprosić w dowolnym momencie.

Strategia: statyczny nagłówek po stronie serwera

Jeśli na serwerze używasz nagłówka User-Agent, a Twoje potrzeby dotyczące tych danych są stosunkowo spójne w całej witrynie, możesz określić odpowiednie wskazówki klienta jako zestaw statyczny w odpowiedziach. Jest to stosunkowo proste podejście, ponieważ wystarczy skonfigurować je w jednym miejscu. Może to być na przykład konfiguracja serwera WWW, jeśli nagłówki są już dodane, konfiguracja hostingu lub konfiguracja najwyższego poziomu platformy lub frameworku używanego w witrynie.

Rozważ tę strategię, jeśli chcesz przekształcać lub dostosowywać odpowiedzi na podstawie danych użytkownika.

Przeglądarki lub inne klienty mogą podawać różne domyślne wskazówki, dlatego warto określić wszystko, czego potrzebujesz, nawet jeśli jest to domyślne.

Na przykład bieżące ustawienia domyślne Chrome będą wyglądać tak:

⬇️ Nagłówki odpowiedzi

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

Jeśli chcesz też otrzymywać w odpowiedziach model urządzenia, wyślij:

⬇️ Nagłówki odpowiedzi

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

Podczas przetwarzania po stronie serwera należy najpierw sprawdzić, czy został wysłany odpowiedni nagłówek Sec-CH-UA, a jeśli nie jest on dostępny, przełączyć się na analizowanie nagłówka User-Agent.

Strategia: delegowanie wskazówek do żądań między domenami

Jeśli wysyłasz żądania zasobów podrzędnych z różnych witryn lub domen, które wymagają wysyłania wskazówek dotyczących klienta User-Agent, musisz wyraźnie określić odpowiednie wskazówki za pomocą zasad dotyczących uprawnień.

Załóżmy na przykład, że https://blog.site hostuje zasoby na serwerze https://cdn.site, który może zwracać zasoby zoptymalizowane pod kątem konkretnego urządzenia. https://blog.site może poprosić o Sec-CH-UA-Model podpowiedź, ale musi wyraźnie przekazać ją https://cdn.site za pomocą nagłówka Permissions-Policy. Lista wskazówek kontrolowanych przez zasady jest dostępna w przeglądzie projektu Wskazówki dotyczące klienta Infrastruktura.

⬇️ Odpowiedź od blog.site, która deleguje podpowiedź

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

⬆️ Żądanie do zasobów podrzędnych na cdn.site zawiera podpowiedź delegowania

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

Możesz podać wiele wskazówek dla wielu źródeł, a nie tylko z zakresu ch-ua:

⬇️ Odpowiedź z blog.site delegująca wiele wskazówek do wielu źródeł

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

Strategia: delegowanie podpowiedzi do elementów iframe

Elementy iframe między domenami działają podobnie jak zasoby między domenami, ale w atrybucie allow musisz podać wskazówki, które chcesz delegować.

⬇️ Odpowiedź użytkownika blog.site

Accept-CH: Sec-CH-UA-Model

↪️ HTML dla blog.site

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

⬆️ Prośba do: widget.site

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

Atrybut allow w ramce iframe zastąpi dowolny nagłówek Accept-CH, który może wysłać widget.site, więc upewnij się, że uwzględniono wszystko, czego potrzebuje strona iframe.

Strategia: dynamiczne wskazówki po stronie serwera

Jeśli w pewnych częściach ścieżki użytkownika potrzebujesz większej liczby podpowiedzi niż w pozostałych częściach witryny, możesz poprosić o te podpowiedzi na żądanie, a nie statycznie w całej witrynie. Jest to bardziej skomplikowane, ale jeśli masz już ustawione różne nagłówki dla poszczególnych tras, może to być możliwe.

Pamiętaj, że każda instancja nagłówka Accept-CH nadpisze istniejący zestaw. Jeśli więc nagłówek jest ustawiany dynamicznie, każda strona musi poprosić o pełny zestaw wymaganych wskazówek.

Możesz na przykład mieć w swojej witrynie sekcję, w której chcesz umieścić ikony i elementy sterujące dostosowane do systemu operacyjnego użytkownika. W tym celu możesz dodatkowo zaimportować Sec-CH-UA-Platform-Version, aby udostępnić odpowiednie zasoby podrzędne.

⬇️ Nagłówki odpowiedzi dla /blog

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

⬇️ Nagłówki odpowiedzi dla /app

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

Strategia: wskazówki po stronie serwera wymagane przy pierwszym żądaniu

Być może w pierwszym żądaniu będziesz potrzebować więcej niż domyślnego zestawu wskazówek, ale jest to mało prawdopodobne, więc sprawdź, czy rozumiesz uzasadnienie.

Pierwsze żądanie to w istocie pierwsze żądanie najwyższego poziomu dla danego źródła, wysłane w ramach danej sesji przeglądania. Domyślny zestaw wskazówek obejmuje nazwę przeglądarki z wersją główną, platformę i wskaźnik mobilności. Pytanie, które tutaj pada, brzmi: czy potrzebujesz rozszerzonych danych dotyczących początkowego wczytania strony?

Aby uzyskać dodatkowe wskazówki dotyczące pierwszej prośby, masz 2 opcje. Po pierwsze, możesz skorzystać z nagłówka Critical-CH. Ma ono ten sam format co Accept-CH, ale informuje przeglądarkę, że jeśli pierwsze żądanie zostało wysłane bez istotnej wskazówki, należy od razu ponownie je przesłać.

⬆️ Wstępne żądanie

[With default headers]

⬇️ Nagłówki odpowiedzi

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

🔃 Przeglądarka ponownie wysyła początkowe żądanie z dodatkowym nagłówkiem

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

Spowoduje to obciążenie związane z ponownym wysłaniem pierwszego żądania, ale koszt wdrożenia jest stosunkowo niski. Wyślij dodatkowy nagłówek, a przeglądarka zajmie się resztą.

W sytuacjach, gdy naprawdę potrzebujesz dodatkowych wskazówek podczas pierwszego wczytywania strony, propozycja dotycząca niezawodności wskazówek klienta przedstawia sposób określania wskazówek w ustawieniach na poziomie połączenia. W tym celu używa rozszerzenia Application-Layer Protocol Settings(ALPS) do TLS 1.3, aby umożliwić wcześniejsze przekazywanie wskazówek w przypadku połączeń HTTP/2 i HTTP/3. Jest to wciąż bardzo wczesny etap, ale jeśli aktywnie zarządzasz własnymi ustawieniami TLS i połączeń, to jest idealny moment, aby się zaangażować.

Strategia: obsługa starszych wersji

W swojej witrynie możesz mieć kod starszy lub kod zewnętrzny, który zależy od wartości navigator.userAgent, w tym fragmentów ciągu tekstowego klienta użytkownika, które zostaną skrócone. W długim okresie warto przejść na równoważne navigator.userAgentDatawybieranie, ale istnieje też tymczasowe rozwiązanie.

UA-CH retrofill to mała biblioteka, która umożliwia zastąpienie wartości navigator.userAgent nowym ciągiem znaków utworzonym na podstawie wartości navigator.userAgentData.

Ten kod wygeneruje ciąg znaków klienta użytkownika, który dodatkowo zawiera podpowiedź „model”:

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

Wygenerowany ciąg znaków zawiera model Pixel 5, ale nadal zawiera skrócony model 92.0.0.0, ponieważ nie przesłano podpowiedzi 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

Dodatkowa pomoc

Jeśli te strategie nie pasują do Twojego przypadku użycia, otwórz dyskusję w repozytorium privacy-sandbox-dev-support, a my pomożemy Ci rozwiązać problem.

Zdjęcie: Ricardo Rocha z Unsplash