Kullanıcı Aracısı İstemci İpuçlarına Taşı

Sitenizi kullanıcı aracısı dizesine dayalı olmaktan yeni Kullanıcı Aracısı İstemci İpuçları'na taşıma stratejileri.

User-Agent dizesinin tarayıcılarda önemli bir pasif parmak izi yüzeyi olmasının yanı sıra işlenmesinin zor olması da söz konusudur. Ancak kullanıcı aracısı verilerini toplama ve işleme konusunda geçerli birçok neden vardır. Bu nedenle, daha iyi bir çözüme giden bir yol gereklidir. Kullanıcı aracısı istemci ipuçları, hem kullanıcı aracısı verilerine olan ihtiyacınızı açıkça belirtmenizi hem de verileri kullanımı kolay bir biçimde döndürme yöntemleri sunar.

Bu makalede, kullanıcı aracısı verilerine erişiminizi denetleme ve kullanıcı aracısı dizesi kullanımını Kullanıcı Aracısı İstemci İpuçları'na taşıma işlemleri açıklanmaktadır.

Kullanıcı aracısı verilerinin toplanması ve kullanımıyla ilgili denetim

Her türlü veri toplama biçiminde olduğu gibi, verileri neden topladığınız her zaman açık olmalıdır. Herhangi bir işlem yapıp yapmayacağınızdan bağımsız olarak ilk adım, kullanıcı aracısı verilerini nerede ve neden kullandığınızı anlamaktır.

Kullanıcı aracısı verilerinin kullanılıp kullanılmadığını veya nerede kullanıldığını bilmiyorsanız ön uç kodunuzda navigator.userAgent, arka uç kodunuzda ise User-Agent HTTP üst bilgisinin kullanılıp kullanılmadığını arayın. Ayrıca, navigator.platform ve navigator.appVersion gibi desteği sonlandırılmış özelliklerin kullanılıp kullanılmadığını kontrol etmek için ön uç kodunuzu da incelemeniz gerekir.

İşlevsel açıdan bakıldığında, kodunuzda kayıt veya işlem yaptığınız her yeri düşünün:

  • Tarayıcı adı veya sürümü
  • İşletim sisteminin adı veya sürümü
  • Cihaz markası veya modeli
  • CPU türü, mimarisi veya bit sayısı (örneğin, 64 bit)

Ayrıca, kullanıcı aracısını işlemek için üçüncü taraf kitaplığı veya hizmeti kullanıyor olabilirsiniz. Bu durumda, Kullanıcı Aracısı İstemci İpuçları'nı desteklemek için güncelleme yapıp yapmadıklarını kontrol edin.

Yalnızca temel kullanıcı aracısı verilerini mi kullanıyorsunuz?

Varsayılan Kullanıcı Aracısı İstemci İpuçları grubu şunları içerir:

  • Sec-CH-UA: tarayıcı adı ve büyük/önemli sürüm
  • Sec-CH-UA-Mobile: Mobil cihazı belirten boole değeri
  • Sec-CH-UA-Platform: işletim sistemi adı
    • Bu durumun spesifikasyonda güncellendiğini ve kısa süre içinde Chrome ile diğer Chromium tabanlı tarayıcılara yansıtılacağını unutmayın.

Önerilen kullanıcı aracısı dizenin azaltılmış sürümü de bu temel bilgileri geriye dönük uyumlu bir şekilde saklar. Örneğin, dize Chrome/90.0.4430.85 yerine Chrome/90.0.0.0 içerir.

User-Agent dizesini yalnızca tarayıcı adı, ana sürüm veya işletim sistemi için kontrol ediyorsanız kodunuz çalışmaya devam eder ancak desteği sonlandırılma uyarıları görebilirsiniz.

Kullanıcı Aracısı İstemci İpuçları'na geçiş yapabilirsiniz ve yapmanız gerekir ancak bunu engelleyen eski kod veya kaynak kısıtlamalarınız olabilir. Kullanıcı aracısı dizesindeki bilgilerin geriye dönük uyumlu bir şekilde azaltılmasıyla, mevcut kodun daha az ayrıntılı bilgi almasına rağmen temel işlevleri koruması amaçlanmıştır.

Strateji: İsteğe bağlı istemci tarafı JavaScript API

Şu anda navigator.userAgent kullanıyorsanız kullanıcı aracısı dizesini ayrıştırmaya geri dönmeden önce navigator.userAgentData'u tercih etmeye geçmeniz gerekir.

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

Mobil cihaz veya masaüstü cihaz olup olmadığını kontrol ediyorsanız boole mobile değerini kullanın:

const isMobile = navigator.userAgentData.mobile;

userAgentData.brands, brand ve version özelliklerine sahip bir nesne dizisidir. Tarayıcı, bu markalarla uyumluluğunu bu nesne dizisinde listeleyebilir. Buna doğrudan bir dizi olarak erişebilir veya belirli bir girişin olup olmadığını kontrol etmek için some() çağrısı kullanabilirsiniz:

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
}

Daha ayrıntılı, yüksek entropili kullanıcı aracısı değerlerinden birine ihtiyacınız varsa bunu belirtmeniz ve döndürülen Promise içinde sonucu kontrol etmeniz gerekir:

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

Sunucu tarafı işleme yerine istemci tarafı işleme geçmek istiyorsanız da bu stratejiyi kullanabilirsiniz. JavaScript API'si HTTP isteği üstbilgilerine erişim gerektirmez. Bu nedenle, kullanıcı aracısı değerleri herhangi bir zamanda istenebilir.

Strateji: Statik sunucu tarafı başlık

Sunucuda User-Agent istek üstbilgisini kullanıyorsanız ve bu verilere olan ihtiyaçlarınız sitenizin tamamında nispeten tutarlıysa istenen istemci ipuçlarını yanıtlarınızda statik bir grup olarak belirtebilirsiniz. Genellikle yalnızca bir yerde yapılandırmanız gerektiğinden bu, nispeten basit bir yaklaşımdır. Örneğin, üstbilgileri zaten web sunucu yapılandırmanıza ekliyorsanız bu yapılandırma, barındırma yapılandırmanızda veya siteniz için kullandığınız çerçevenin ya da platformun üst düzey yapılandırmasında olabilir.

Kullanıcı aracısı verilerine göre sunulan yanıtları dönüştürüyor veya özelleştiriyorsanız bu stratejiyi kullanabilirsiniz.

Tarayıcılar veya diğer istemciler farklı varsayılan ipuçları sunmayı seçebilir. Bu nedenle, genellikle varsayılan olarak sağlansa bile ihtiyacınız olan her şeyi belirtmeniz önerilir.

Örneğin, Chrome'un mevcut varsayılanları şu şekilde gösterilir:

⬇️ Yanıt başlıkları

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

Yanıtlarda cihaz modelini de almak istiyorsanız şunu gönderirsiniz:

⬇️ Yanıt başlıkları

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

Bunu sunucu tarafında işlerken önce istenen Sec-CH-UA başlığının gönderilip gönderilmediğini kontrol etmeniz, ardından mevcut değilse User-Agent başlığı ayrıştırmaya geçmeniz gerekir.

Strateji: Kaynaklar arası isteklere ipucu verme

İstemlerinde Kullanıcı Aracısı İstemci İpuçları'nın gönderilmesini gerektiren kaynak veya siteler arası alt kaynaklar istiyorsanız izin politikası kullanarak istenen ipuçlarını açıkça belirtmeniz gerekir.

Örneğin, https://blog.site'ün, belirli bir cihaz için optimize edilmiş kaynakları döndürebilecek kaynakları https://cdn.site üzerinde barındırdığını varsayalım. https://blog.site, Sec-CH-UA-Model ipucunu isteyebilir ancak Permissions-Policy başlığını kullanarak bunu https://cdn.site'ye açıkça devretmesi gerekir. Politika kontrollü ipuçları listesini Clients Hints Infrastructure draft (İstemci İpuçları Altyapısı taslağı) belgesinde bulabilirsiniz.

⬇️ blog.site tarafından ipucu devredilen yanıt

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

⬆️ cdn.site'teki alt kaynaklardan, devredilen ipucunu içermesini isteyin

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

Yalnızca ch-ua aralığındaki kaynaklar için değil, birden fazla kaynak için birden fazla ipucu belirtebilirsiniz:

⬇️ Birden fazla ipucu birden fazla kaynağa delege eden blog.site'ten gelen yanıt

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

Strateji: İpuçları iframe'lere devretme

Kaynaklar arası iframe'ler, kaynakta farklı olan kaynaklara benzer şekilde çalışır ancak yetki vermek istediğiniz ipuçlarını allow özelliğinde belirtirsiniz.

⬇️ blog.site tarafından verilen yanıt

Accept-CH: Sec-CH-UA-Model

↪️ blog.site için HTML

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

⬆️ widget.site adlı kullanıcıya istek gönderildi

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

iFrame'deki allow özelliği, widget.site'nin gönderebileceği tüm Accept-CH üstbilgilerini geçersiz kılar. Bu nedenle, iFrame'deki sitenin ihtiyaç duyacağı her şeyi belirttiğinizden emin olun.

Strateji: Dinamik sunucu tarafı ipuçları

Kullanıcı yolculuğunun, sitenin geri kalanına kıyasla daha fazla ipucu seçeneğinizin gerektiği belirli bölümleri varsa bu ipuçlarını sitenin tamamında statik olarak değil, isteğe bağlı olarak isteyebilirsiniz. Bu yöntemin yönetimi daha karmaşıktır ancak rota bazında farklı başlıklar ayarladıysanız bu yöntemi kullanabilirsiniz.

Burada dikkat edilmesi gereken önemli nokta, Accept-CH başlığının her örneğinin mevcut ayarın üzerine etkili bir şekilde yazacağıdır. Bu nedenle, başlığı dinamik olarak ayarlıyorsanız her sayfanın gerekli ipuçlarının tamamını istemesi gerekir.

Örneğin, sitenizde kullanıcının işletim sistemiyle eşleşen simgeler ve kontroller sunmak istediğiniz bir bölüm olabilir. Bunun için, uygun alt kaynakları yayınlamak üzere Sec-CH-UA-Platform-Version'ü de dahil edebilirsiniz.

⬇️ /blog için yanıt başlıkları

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

⬇️ /app için yanıt başlıkları

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

Strateji: İlk istekte sunucu tarafı ipuçları gerekli

İlk istekte varsayılan ipucu grubundan daha fazlasına ihtiyacınız olabileceği durumlar olabilir. Ancak bu durum nadirdir. Bu nedenle, gerekçeyi incelediğinizden emin olun.

İlk istek, aslında söz konusu tarama oturumunda gönderilen, söz konusu kaynak için ilk üst düzey istek anlamına gelir. Varsayılan ipucu grubu, ana sürümü içeren tarayıcı adını, platformu ve mobil göstergeyi içerir. Burada sorulması gereken soru, ilk sayfa yüklemesinde genişletilmiş verilere ihtiyacınız olup olmadığıdır.

İlk istekle ilgili ek ipuçları için iki seçenek vardır. Öncelikle Critical-CH başlığını kullanabilirsiniz. Bu, Accept-CH ile aynı biçime sahiptir ancak tarayıcıya, ilk istek kritik ipucu olmadan gönderildiyse isteği hemen yeniden denemesi gerektiğini söyler.

⬆️ İlk istek

[With default headers]

⬇️ Yanıt başlıkları

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

🔃 Tarayıcı, ilk isteği ek üstbilgeyle yeniden dener

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

Bu, ilk istekte yeniden deneme masrafına neden olur ancak uygulama maliyeti nispeten düşüktür. Ek başlığı gönderin. Gerisi tarayıcı tarafından yapılır.

İlk sayfa yüklemesinde gerçekten ek ipuçlarına ihtiyaç duyduğunuz durumlarda İstemci İpuçları Güvenilirliği önerisi, bağlantı düzeyindeki ayarlarda ipuçlarını belirtmek için bir rota sunar. Bu, HTTP/2 ve HTTP/3 bağlantılarında ipuçlarının erken aktarılmasını sağlamak için TLS 1.3'teki Uygulama Katmanı Protokol Ayarları(ALPS) uzantısından yararlanır. Bu proje henüz çok erken bir aşamada olsa da kendi TLS ve bağlantı ayarlarınızı etkin bir şekilde yönetiyorsanız katkıda bulunmak için ideal bir zamandır.

Strateji: Eski destek

Sitenizde, kullanıcı aracısı dizenin azaltılacak bölümleri de dahil olmak üzere navigator.userAgent'e dayalı eski veya üçüncü taraf kodlarınız olabilir. Uzun vadede eşdeğer navigator.userAgentData çağrılarına geçmeyi planlamanız gerekir ancak geçici bir çözüm de vardır.

UA-CH retrofill, navigator.userAgent değerinin üzerine istenen navigator.userAgentData değerlerinden oluşturulan yeni bir dizeyle yazmanıza olanak tanıyan küçük bir kitaplıktır.

Örneğin, bu kod "model" ipucunu da içeren bir kullanıcı aracısı dizesi oluşturur:

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

Elde edilen dize, Pixel 5 modelini gösterir ancak uaFullVersion ipucu istenmediği için azaltılmış 92.0.0.0 değerini göstermeye devam eder:

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

Daha fazla destek

Bu stratejiler kullanım alanınızı kapsamıyorsa lütfen privacy-sandbox-dev-support reposunda bir tartışma başlatın. Böylece sorununuzu birlikte inceleyebiliriz.

Fotoğraf: Unsplash'taki Ricardo Rocha