Strategie migracji witryny z ciągu znaków klienta użytkownika na nowy interfejs User-Agent Client Hints.
Opublikowano: 19 maja 2021 r.
Ciąg znaków User-Agent to istotna pasywna powierzchnia odcisków cyfrowych w przeglądarkach, która jest trudna do przetworzenia. Istnieje jednak wiele uzasadnionych powodów zbierania i przetwarzania danych klienta użytkownika, dlatego potrzebne jest lepsze rozwiązanie. Interfejs User-Agent Client Hints zapewnia zarówno jednoznaczny sposób deklarowania zapotrzebowania na dane klienta użytkownika, jak i metody zwracania danych w łatwym w użyciu formacie.
W tym artykule opisujemy, jak sprawdzić dostęp do danych klienta użytkownika i przenieść ciąg znaków klienta użytkownika do interfejsu User-Agent Client Hints.
Kontrola zbierania i wykorzystywania danych klienta użytkownika
Podobnie jak w przypadku każdej formy zbierania danych, zawsze musisz wiedzieć, dlaczego je zbierasz. Pierwszym krokiem, niezależnie od tego, czy podejmiesz jakieś działania, jest zrozumienie, gdzie i dlaczego używasz danych klienta użytkownika.
Jeśli nie wiesz, czy i gdzie są używane dane klienta użytkownika, wyszukaj w kodzie frontendu ciąg navigator.userAgent, a w kodzie backendu – nagłówek HTTP User-Agent. Sprawdź też, czy w kodzie frontendu nie są używane wycofane już funkcje, takie jak navigator.platform i navigator.appVersion.
Z funkcjonalnego punktu widzenia zastanów się, gdzie w kodzie rejestrujesz lub przetwarzasz:
- Nazwa lub wersja przeglądarki
- Nazwa lub wersja systemu operacyjnego
- marka lub model urządzenia,
- typ procesora, architektura lub liczba bitów (np. 64-bitowy);
Możliwe też, że do przetwarzania klienta użytkownika używasz biblioteki lub usługi innej firmy. W takim przypadku sprawdź, czy dostawca aktualizuje swoje usługi, aby obsługiwały interfejs User-Agent Client Hints.
Czy używasz tylko podstawowych danych klienta użytkownika?
Domyślny zestaw interfejsu User-Agent Client Hints obejmuje:
Sec-CH-UA: nazwa przeglądarki i jej wersja główna lub znacząca,Sec-CH-UA-Mobile: wartość logiczna wskazująca urządzenie mobilne.Sec-CH-UA-Platform: nazwa systemu operacyjnego
Proponowana zredukowana wersja ciągu znaków klienta użytkownika również będzie zachowywać te podstawowe informacje w sposób zgodny wstecznie. Na przykład zamiast Chrome/90.0.4430.85 ciąg będzie zawierać Chrome/90.0.0.0.
Jeśli sprawdzasz ciąg znaków klienta użytkownika tylko pod kątem nazwy przeglądarki, wersji głównej lub systemu operacyjnego, kod będzie nadal działać, ale prawdopodobnie zobaczysz ostrzeżenia o wycofaniu.
Możesz i powinieneś przejść na interfejs User-Agent Client Hints, ale może to być niemożliwe ze względu na starszy kod lub ograniczenia zasobów. Zmniejszenie ilości informacji w ciągu znaków klienta użytkownika w sposób zgodny wstecznie ma na celu zapewnienie, że istniejący kod będzie otrzymywać mniej szczegółowe informacje, ale zachowa podstawowe funkcje.
Strategie
Istnieje wiele strategii, które możesz zastosować, aby przejść z ciągu znaków klienta użytkownika na interfejs User-Agent Client Hints.
Interfejs JavaScript API po stronie klienta na żądanie
Jeśli używasz navigator.userAgent, przejdź na navigator.userAgentData, zanim wrócisz do analizowania ciągu znaków klienta użytkownika.
if (navigator.userAgentData) {
// use new hints
} else {
// fall back to user-agent string parsing
}
Jeśli sprawdzasz, czy urządzenie jest komórką lub komputerem, użyj wartości logicznej mobile:
const isMobile = navigator.userAgentData.mobile;
userAgentData.brands to tablica obiektów z właściwościami brand i version, w której przeglądarka może wyświetlić listę zgodności z tymi markami. Możesz uzyskać do niego dostęp bezpośrednio jako do tablicy lub użyć wywołania some(), aby sprawdzić, czy dany wpis jest obecny:
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 jednej z bardziej szczegółowych wartości klienta użytkownika o wysokiej entropii, musisz ją określić i sprawdzić wynik w zwróconym obiekcie 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 żądać w dowolnym momencie.
Statyczny nagłówek po stronie serwera
Jeśli na serwerze używasz nagłówka żądania User-Agent, a Twoje potrzeby dotyczące tych danych są względnie spójne w całej witrynie, możesz określić wskazówki dotyczące klienta jako statyczny zestaw w odpowiedziach. Jest to stosunkowo proste podejście, ponieważ zwykle wystarczy skonfigurować je w jednym miejscu. Może to być na przykład konfiguracja serwera WWW, jeśli dodajesz już tam nagłówki, konfiguracja hostingu lub konfiguracja najwyższego poziomu platformy, której używasz w witrynie.
Rozważ tę strategię, jeśli przekształcasz lub dostosowujesz odpowiedzi wyświetlane na podstawie danych klienta użytkownika.
Przeglądarki lub inne klienty mogą podawać inne domyślne wskazówki, dlatego warto określić wszystko, czego potrzebujesz, nawet jeśli jest to zwykle podawane domyślnie.
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 tego 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, przejść do analizy nagłówka User-Agent.
Przekazywanie wskazówek do żądań z innej domeny
Jeśli żądasz zasobów podrzędnych ze współdzielonych domen lub witryn, które wymagają wysyłania interfejsu User-Agent Client Hints w żądaniach, musisz wyraźnie określić żądane wskazówki za pomocą zasad dotyczących uprawnień.
Załóżmy na przykład, że https://blog.site hostuje zasoby na https://cdn.site, które mogą zwracać zasoby zoptymalizowane pod kątem konkretnego urządzenia.
https://blog.site może poprosić o wskazówkę Sec-CH-UA-Model, ale musi wyraźnie przekazać ją do https://cdn.site za pomocą nagłówka Permissions-Policy. Lista wskazówek kontrolowanych przez zasady jest dostępna w wersji roboczej infrastruktury wskazówek dotyczących klienta.
⬇️ Odpowiedź od blog.site przekazującego wskazówkę
Accept-CH: Sec-CH-UA-Model
Permissions-Policy: ch-ua-model=(self "https://cdn.site")
⬆️ Żądania do zasobów podrzędnych w cdn.site zawierają wskazówkę dotyczącą przekazania
Sec-CH-UA-Model: "Pixel 5"
Możesz określić wiele wskazówek dla wielu źródeł, nie tylko z zakresu ch-ua:
⬇️ Odpowiedź z blog.site przekazują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")
Przekazywanie wskazówek do elementów iframe
Elementy iframe ze współdzieleniem działają podobnie do zasobów ze współdzieleniem, ale wskazówki, które chcesz przekazać, określasz w atrybucie allow.
⬇️ Odpowiedź od: blog.site
Accept-CH: Sec-CH-UA-Model
↪️ Kod 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 elemencie iframe zastąpi każdy nagłówek Accept-CH, który widget.site może wysłać, więc upewnij się, że podano wszystkie informacje, których będzie potrzebować witryna w elemencie iframe.
Dynamiczne wskazówki po stronie serwera
Jeśli masz określone części ścieżki użytkownika, w których potrzebujesz większego wyboru wskazówek niż w pozostałej części witryny, możesz poprosić o te wskazówki na żądanie, a nie statycznie w całej witrynie. Zarządzanie tym jest bardziej skomplikowane, ale jeśli masz już ustawione różne nagłówki dla poszczególnych tras, może to być wykonalne.
Pamiętaj, że każde wystąpienie nagłówka Accept-CH skutecznie zastąpi istniejący zestaw. Jeśli więc nagłówek jest ustawiany dynamicznie, każda strona musi żądać pełnego zestawu wymaganych wskazówek.
Załóżmy, że masz w witrynie sekcję, w której chcesz wyświetlać ikony i elementy sterujące pasujące do systemu operacyjnego użytkownika. W tym celu możesz dodatkowo pobrać Sec-CH-UA-Platform-Version, aby wyświetlać 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
Rozwiązywanie problemu ze wskazówkami po stronie serwera wymaganymi przy pierwszym żądaniu
W niektórych przypadkach możesz potrzebować więcej niż domyślnego zestawu wskazówek już przy pierwszym żądaniu, ale prawdopodobnie będzie to rzadkie, więc upewnij się, że masz ku temu powód.
Pierwsze żądanie to pierwsze żądanie najwyższego poziomu wysłane do tego źródła w danej sesji przeglądania. Domyślny zestaw wskazówek obejmuje nazwę przeglądarki z wersją główną, platformę i wskaźnik urządzenia mobilnego. Warto więc zadać sobie pytanie, czy potrzebujesz rozszerzonych danych przy pierwszym wczytaniu strony.
Aby uzyskać dodatkowe wskazówki dotyczące pierwszej prośby, masz 2 opcje. Po pierwsze możesz użyć nagłówka Critical-CH. Ma on taki sam format jak Accept-CH, ale informuje przeglądarkę, że powinna natychmiast ponowić żądanie, jeśli pierwsze zostało wysłane bez wskazówki krytycznej.
⬆️ Pierwotne żądanie
[With default headers]
⬇️ Nagłówki odpowiedzi
Accept-CH: Sec-CH-UA-Model
Critical-CH: Sec-CH-UA-Model
🔃 Przeglądarka ponawia początkowe żądanie z dodatkowym nagłówkiem.
[With default headers + …]
Sec-CH-UA-Model: Pixel 5
Wiąże się to z narzutem ponownej próby przy pierwszym żądaniu, 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 przy pierwszym wczytaniu strony, propozycja dotycząca niezawodności wskazówek klienta określa sposób podawania wskazówek w ustawieniach na poziomie połączenia. Wykorzystuje ono rozszerzenie Application-Layer Protocol Settings (ALPS) protokołu TLS 1.3, aby umożliwić wcześniejsze przekazywanie wskazówek w połączeniach HTTP/2 i HTTP/3. To rozwiązanie jest jeszcze na bardzo wczesnym etapie, ale jeśli aktywnie zarządzasz własnymi ustawieniami TLS i połączeń, to idealny moment, aby wnieść swój wkład.
Pomoc dotycząca starszych wersji
W Twojej witrynie może znajdować się starszy lub zewnętrzny kod, który zależy od navigator.userAgent, w tym części ciągu znaków klienta użytkownika, które zostaną ograniczone. Zalecamy przejście na odpowiednie wywołania navigator.userAgentData, ale istnieje rozwiązanie tymczasowe.
UA-CH retrofill to niewielka biblioteka, która umożliwia zastąpienie navigator.userAgent nowym ciągiem znaków utworzonym na podstawie żądanych wartości navigator.userAgentData.
Na przykład ten kod generuje ciąg znaków klienta użytkownika, który dodatkowo zawiera wskazówkę „model”:
import { overrideUserAgentUsingClientHints } from './uach-retrofill.js';
overrideUserAgentUsingClientHints(['model'])
.then(() => { console.log(navigator.userAgent); });
Wynikowy ciąg znaków będzie zawierał model Pixel 5, ale nadal będzie wyświetlał skróconą wartość 92.0.0.0, ponieważ nie zażądano wskazówki 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
Dalsza pomoc
Jeśli te strategie nie pasują do Twojego przypadku użycia, rozpocznij dyskusję w repozytorium privacy-sandbox-dev-support, abyśmy mogli wspólnie przeanalizować Twój problem.