Strategi untuk memigrasikan situs Anda dari mengandalkan string agen pengguna ke Client Hints Agen Pengguna baru.
String Agen Pengguna adalah platform pelacakan sidik jari pasif yang signifikan di browser, serta sulit diproses. Namun, ada berbagai alasan yang valid untuk mengumpulkan dan memproses data agen pengguna, sehingga yang diperlukan adalah jalur menuju solusi yang lebih baik. User-Agent Client Hints memberikan cara eksplisit untuk mendeklarasikan kebutuhan Anda akan data dan metode user-agent untuk menampilkan data dalam format yang mudah digunakan.
Artikel ini akan memandu Anda mengaudit akses ke data agen pengguna dan memigrasikan penggunaan string agen pengguna ke Client Hints Agen Pengguna.
Mengaudit pengumpulan dan penggunaan data agen pengguna
Seperti segala bentuk pengumpulan data, Anda harus selalu memahami alasan mengumpulkannya. Langkah pertama, terlepas dari apakah Anda akan mengambil tindakan apa pun, adalah memahami di mana dan mengapa Anda menggunakan data agen pengguna.
Jika Anda tidak tahu apakah atau di mana data agen pengguna digunakan, pertimbangkan untuk menelusuri
kode frontend untuk penggunaan navigator.userAgent
dan kode backend untuk
penggunaan header HTTP User-Agent
. Anda juga harus memeriksa kode frontend untuk mengetahui penggunaan fitur yang sudah tidak digunakan lagi, seperti navigator.platform
dan navigator.appVersion
.
Dari sudut pandang fungsional, pertimbangkan bagian mana pun dalam kode tempat Anda merekam atau memproses:
- Nama atau versi browser
- Nama atau versi sistem operasi
- Merek atau model perangkat
- Jenis, arsitektur, atau bit CPU (misalnya, 64-bit)
Anda mungkin juga menggunakan library atau layanan pihak ketiga untuk memproses agen pengguna. Dalam hal ini, periksa apakah browser tersebut diupdate untuk mendukung Client Hints Agen Pengguna.
Apakah Anda hanya menggunakan data agen pengguna dasar?
Kumpulan default Petunjuk Klien Agen Pengguna mencakup:
Sec-CH-UA
: nama browser dan versi utama/signifikanSec-CH-UA-Mobile
: nilai boolean yang menunjukkan perangkat selulerSec-CH-UA-Platform
: nama sistem operasi- Perhatikan bahwa hal ini telah diperbarui dalam spesifikasi dan akan ditampilkan di Chrome dan browser berbasis Chromium lainnya dalam waktu dekat.
Versi string agen pengguna yang dikurangi yang diusulkan juga akan mempertahankan
informasi dasar ini dengan cara yang kompatibel dengan versi sebelumnya. Misalnya, string akan menyertakan Chrome/90.0.0.0
, bukan
Chrome/90.0.4430.85
.
Jika Anda hanya memeriksa string agen pengguna untuk nama browser, versi utama, atau sistem operasi, kode akan terus berfungsi meskipun Anda mungkin melihat peringatan penghentian penggunaan.
Meskipun dapat dan harus bermigrasi ke Petunjuk Klien Agen Pengguna, Anda mungkin memiliki batasan resource atau kode lama yang mencegah hal ini. Pengurangan informasi dalam string agen pengguna dengan cara yang kompatibel dengan versi sebelumnya ini dimaksudkan untuk memastikan bahwa meskipun kode yang ada akan menerima informasi yang kurang mendetail, kode tersebut masih harus mempertahankan fungsi dasar.
Strategi: JavaScript API sisi klien on demand
Jika saat ini Anda menggunakan navigator.userAgent
, Anda harus bertransisi untuk
memilih navigator.userAgentData
sebelum kembali mengurai
string agen pengguna.
if (navigator.userAgentData) {
// use new hints
} else {
// fall back to user-agent string parsing
}
Jika Anda memeriksa perangkat seluler atau desktop, gunakan nilai boolean mobile
:
const isMobile = navigator.userAgentData.mobile;
userAgentData.brands
adalah array objek dengan properti brand
dan version
tempat browser dapat mencantumkan kompatibilitasnya dengan merek
tersebut. Anda dapat mengaksesnya langsung sebagai array atau Anda dapat menggunakan
panggilan some()
untuk memeriksa apakah entri tertentu ada:
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
}
Jika memerlukan salah satu nilai agen pengguna yang lebih mendetail dan entropi tinggi, Anda harus menentukannya dan memeriksa hasilnya dalam Promise
yang ditampilkan:
navigator.userAgentData.getHighEntropyValues(['model'])
.then(ua => {
// requested hints available as attributes
const model = ua.model
});
Anda juga dapat menggunakan strategi ini jika ingin beralih dari pemrosesan sisi server ke pemrosesan sisi klien. JavaScript API tidak memerlukan akses ke header permintaan HTTP, sehingga nilai agen pengguna dapat diminta kapan saja.
Strategi: Header sisi server statis
Jika Anda menggunakan header permintaan User-Agent
di server dan kebutuhan Anda
untuk data tersebut relatif konsisten di seluruh situs, Anda dapat
menentukan petunjuk klien yang diinginkan sebagai kumpulan statis dalam respons Anda. Ini adalah
pendekatan yang relatif sederhana karena Anda umumnya hanya perlu mengonfigurasinya di satu
lokasi. Misalnya, header tersebut mungkin ada di konfigurasi server web jika Anda sudah
menambahkan header di sana, konfigurasi hosting, atau konfigurasi tingkat teratas
framework atau platform yang Anda gunakan untuk situs Anda.
Pertimbangkan strategi ini jika Anda mengubah atau menyesuaikan respons yang ditayangkan berdasarkan data agen pengguna.
Browser atau klien lain dapat memilih untuk memberikan petunjuk default yang berbeda, jadi sebaiknya tentukan semua yang Anda perlukan, meskipun umumnya disediakan secara default.
Misalnya, setelan default saat ini untuk Chrome akan direpresentasikan sebagai:
⬇️ Header respons
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA
Jika Anda juga ingin menerima model perangkat dalam respons, Anda harus mengirim:
⬇️ Header respons
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA
Saat memprosesnya di sisi server, Anda harus memeriksa terlebih dahulu apakah header Sec-CH-UA
yang diinginkan telah dikirim, lalu kembali ke penguraian header User-Agent
jika tidak tersedia.
Strategi: Mendelegasikan petunjuk ke permintaan lintas origin
Jika Anda meminta sub-resource lintas origin atau lintas situs yang memerlukan Client Hints Agen Pengguna untuk dikirim pada permintaannya, Anda harus menentukan petunjuk yang diinginkan secara eksplisit menggunakan Kebijakan Izin.
Misalnya, https://blog.site
menghosting resource di
https://cdn.site
yang dapat menampilkan resource yang dioptimalkan untuk perangkat tertentu.
https://blog.site
dapat meminta petunjuk Sec-CH-UA-Model
, tetapi perlu
mendelegasikan secara eksplisit ke https://cdn.site
menggunakan header
Permissions-Policy
. Daftar petunjuk yang dikontrol kebijakan tersedia di draf Infrastruktur
Client Hints
⬇️ Respons dari blog.site
yang mendelegasikan petunjuk
Accept-CH: Sec-CH-UA-Model
Permissions-Policy: ch-ua-model=(self "https://cdn.site")
⬆️ Permintaan ke subresource di cdn.site
menyertakan petunjuk yang didelegasikan
Sec-CH-UA-Model: "Pixel 5"
Anda dapat menentukan beberapa petunjuk untuk beberapa origin, dan bukan hanya dari rentang ch-ua
:
⬇️ Respons dari blog.site
yang mendelegasikan beberapa petunjuk ke beberapa origin
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")
Strategi: Mendelegasikan petunjuk ke iframe
Iframe lintas origin berfungsi dengan cara yang mirip dengan resource lintas origin, tetapi Anda
menentukan petunjuk yang ingin didelegasikan dalam atribut allow
.
⬇️ Respons dari blog.site
Accept-CH: Sec-CH-UA-Model
↪️ HTML untuk blog.site
<iframe src="https://widget.site" allow="ch-ua-model"></iframe>
⬆️ Permintaan ke widget.site
Sec-CH-UA-Model: "Pixel 5"
Atribut allow
di iframe akan mengganti header Accept-CH
apa pun yang
dapat dikirim oleh widget.site
, jadi pastikan Anda telah menentukan semua yang
diperlukan situs iframe.
Strategi: Petunjuk sisi server dinamis
Jika Anda memiliki bagian tertentu dari perjalanan pengguna yang memerlukan lebih banyak pilihan petunjuk daripada di seluruh situs, Anda dapat memilih untuk meminta petunjuk tersebut sesuai permintaan, bukan secara statis di seluruh situs. Hal ini lebih rumit untuk dikelola, tetapi jika Anda sudah menetapkan header yang berbeda berdasarkan per rute, hal ini mungkin dapat dilakukan.
Hal penting yang harus diingat di sini adalah setiap instance header Accept-CH
akan secara efektif menimpa kumpulan yang ada. Jadi, jika Anda menetapkan header secara
dinamis, setiap halaman harus meminta kumpulan petunjuk lengkap yang diperlukan.
Misalnya, Anda mungkin memiliki satu bagian di situs tempat Anda ingin menyediakan ikon dan kontrol yang cocok dengan sistem operasi pengguna. Untuk itu, Anda mungkin
ingin menarik Sec-CH-UA-Platform-Version
secara tambahan untuk menayangkan subresource
yang sesuai.
⬇️ Header respons untuk /blog
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA
⬇️ Header respons untuk /app
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA
Strategi: Petunjuk sisi server diperlukan pada permintaan pertama
Mungkin ada kasus saat Anda memerlukan lebih dari kumpulan petunjuk default pada permintaan pertama, tetapi hal ini kemungkinan jarang terjadi, jadi pastikan Anda telah meninjau alasannya.
Permintaan pertama benar-benar berarti permintaan tingkat teratas pertama untuk origin tersebut yang dikirim dalam sesi penjelajahan tersebut. Kumpulan petunjuk default mencakup nama browser dengan versi utama, platform, dan indikator seluler. Jadi, pertanyaan yang harus diajukan di sini adalah, apakah Anda memerlukan data yang diperluas pada pemuatan halaman awal?
Untuk petunjuk tambahan pada permintaan pertama, ada dua opsi. Pertama, Anda dapat
menggunakan header Critical-CH
. Tindakan ini menggunakan format yang sama dengan Accept-CH
,
tetapi memberi tahu browser bahwa permintaan harus segera mencoba lagi jika permintaan pertama
dikirim tanpa petunjuk penting.
⬆️ Permintaan awal
[With default headers]
⬇️ Header respons
Accept-CH: Sec-CH-UA-Model
Critical-CH: Sec-CH-UA-Model
🔃 Browser mencoba ulang permintaan awal dengan header tambahan
[With default headers + …]
Sec-CH-UA-Model: Pixel 5
Hal ini akan menimbulkan overhead percobaan ulang pada permintaan pertama, tetapi biaya penerapannya relatif rendah. Kirim header tambahan dan browser akan melakukan sisanya.
Jika Anda benar-benar memerlukan petunjuk tambahan saat pemuatan halaman pertama dilakukan, proposal Keandalan Petunjuk Klien menjabarkan rute untuk menentukan petunjuk di setelan tingkat koneksi. Hal ini menggunakan ekstensi Application-Layer Protocol Settings(ALPS) ke TLS 1.3 untuk mengaktifkan penerusan petunjuk awal ini pada koneksi HTTP/2 dan HTTP/3. Hal ini masih dalam tahap yang sangat awal, tetapi jika Anda secara aktif mengelola setelan TLS dan koneksi Anda sendiri, ini adalah waktu yang ideal untuk berkontribusi.
Strategi: Dukungan lama
Anda mungkin memiliki kode lama atau pihak ketiga di situs yang bergantung pada
navigator.userAgent
, termasuk bagian string agen pengguna yang akan
dikurangi. Dalam jangka panjang, Anda harus merencanakan untuk beralih ke panggilan navigator.userAgentData
yang setara, tetapi ada solusi sementara.
Retrofill UA-CH adalah library kecil yang memungkinkan Anda menimpa navigator.userAgent
dengan string baru yang dibuat dari nilai navigator.userAgentData
yang diminta.
Misalnya, kode ini akan menghasilkan string agen pengguna yang juga menyertakan petunjuk "model":
import { overrideUserAgentUsingClientHints } from './uach-retrofill.js';
overrideUserAgentUsingClientHints(['model'])
.then(() => { console.log(navigator.userAgent); });
String yang dihasilkan akan menampilkan model Pixel 5
, tetapi masih menampilkan
92.0.0.0
yang dikurangi karena petunjuk uaFullVersion
tidak diminta:
Mozilla/5.0 (Linux; Android 10.0; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.0.0 Mobile Safari/537.36
Dukungan lebih lanjut
Jika strategi ini tidak mencakup kasus penggunaan Anda, mulai Diskusi di repo privacy-sandbox-dev-support dan kita dapat mempelajari masalah Anda bersama-sama.
Foto oleh Ricardo Rocha di Unsplash