उपयोगकर्ता-एजेंट क्लाइंट हिंट पर माइग्रेट करना

आपकी साइट को उपयोगकर्ता-एजेंट स्ट्रिंग के बजाय नए उपयोगकर्ता-एजेंट क्लाइंट हिंट पर माइग्रेट करने की रणनीतियां.

उपयोगकर्ता-एजेंट स्ट्रिंग, ब्राउज़र में एक अहम पैसिव फ़िंगरप्रिंटिंग सतह होती है. साथ ही, इसे प्रोसेस करना भी मुश्किल होता है. हालांकि, उपयोगकर्ता-एजेंट का डेटा इकट्ठा करने और उसे प्रोसेस करने की सभी तरह की मान्य वजहें होती हैं. इसलिए, इस समस्या को बेहतर तरीके से हल करने के तरीके की ज़रूरत है. उपयोगकर्ता-एजेंट क्लाइंट हिंट, दोनों को साफ़ तौर पर यह बताने का एक तरीका होता है कि आपको उपयोगकर्ता-एजेंट डेटा की ज़रूरत है या नहीं. साथ ही, इससे डेटा को आसानी से इस्तेमाल किए जा सकने वाले फ़ॉर्मैट में दिखाया जा सकता है.

इस लेख में आपको उपयोगकर्ता-एजेंट डेटा के ऐक्सेस की जांच करने और उपयोगकर्ता-एजेंट स्ट्रिंग के इस्तेमाल को उपयोगकर्ता-एजेंट क्लाइंट हिंट पर माइग्रेट करने के बारे में जानकारी दी गई है.

उपयोगकर्ता-एजेंट के डेटा को इकट्ठा और इस्तेमाल करने का ऑडिट करना

डेटा इकट्ठा करने के किसी भी अन्य तरीके की तरह, आपको हमेशा इस बात की जानकारी होनी चाहिए कि उसे क्यों इकट्ठा किया जा रहा है. पहला कदम, इस बात से कोई फ़र्क़ नहीं पड़ता कि आप कोई कार्रवाई करने वाले हैं या नहीं, यह समझना है कि उपयोगकर्ता-एजेंट डेटा का इस्तेमाल कहां और क्यों किया जा रहा है.

अगर आपको नहीं पता कि उपयोगकर्ता-एजेंट डेटा का इस्तेमाल कहां किया जा रहा है या कहां किया जा रहा है, तो navigator.userAgent के इस्तेमाल के लिए फ़्रंट-एंड कोड और User-Agent एचटीटीपी हेडर का इस्तेमाल करने के लिए, बैक-एंड कोड खोजें. पहले से काम न करने वाली सुविधाओं, जैसे कि navigator.platform और navigator.appVersion के इस्तेमाल के लिए, आपको अपने फ़्रंट-एंड कोड की भी जांच करनी चाहिए.

काम करने के लिहाज़ से, अपने कोड में उस जगह के बारे में सोचें जहां रिकॉर्डिंग या प्रोसेस की जा रही है:

  • ब्राउज़र का नाम या वर्शन
  • ऑपरेटिंग सिस्टम का नाम या वर्शन
  • डिवाइस का ब्रैंड या मॉडल
  • सीपीयू का टाइप, आर्किटेक्चर या बिटनेस (उदाहरण के लिए, 64-बिट)

यह भी संभावना है कि उपयोगकर्ता-एजेंट को प्रोसेस करने के लिए, किसी तीसरे पक्ष की लाइब्रेरी या सेवा का इस्तेमाल किया जा रहा हो. इस मामले में, देखें कि क्या वे उपयोगकर्ता-एजेंट क्लाइंट हिंट के हिसाब से अपडेट हो रहे हैं.

क्या आप सिर्फ़ उपयोगकर्ता-एजेंट का बुनियादी डेटा इस्तेमाल कर रहे हैं?

उपयोगकर्ता-एजेंट क्लाइंट हिंट के डिफ़ॉल्ट सेट में ये शामिल हैं:

सुझाई गई उपयोगकर्ता-एजेंट स्ट्रिंग के कम किए गए वर्शन में भी इस बुनियादी जानकारी को, पुराने सिस्टम के साथ काम करने के तरीके से बनाए रखा जाएगा. उदाहरण के लिए, Chrome/90.0.4430.85 के बजाय, स्ट्रिंग में Chrome/90.0.0.0 शामिल होगा.

अगर उपयोगकर्ता-एजेंट स्ट्रिंग की जांच सिर्फ़ ब्राउज़र के नाम, मेजर वर्शन या ऑपरेटिंग सिस्टम के लिए की जा रही है, तो आपका कोड काम करता रहेगा. हालांकि, आपको एपीआई के बंद होने की चेतावनियां दिख सकती हैं.

हालांकि, User-Agent क्लाइंट हिंट पर माइग्रेट किया जा सकता है और आपको ऐसा करना चाहिए, लेकिन ऐसा लेगसी कोड या रिसॉर्स से जुड़ी पाबंदियों की वजह से हो सकता है. पुराने सिस्टम के साथ काम करने की सुविधा के तहत, उपयोगकर्ता-एजेंट स्ट्रिंग में जानकारी को कम करने का मकसद यह पक्का करना है कि मौजूदा कोड के बारे में कम जानकारी दी जाए, लेकिन यह ज़रूरी है कि वह अपनी बुनियादी सुविधाओं को बरकरार रखे.

रणनीति: मांग पर उपलब्ध क्लाइंट-साइड JavaScript API

अगर फ़िलहाल navigator.userAgent का इस्तेमाल किया जा रहा है, तो उपयोगकर्ता-एजेंट स्ट्रिंग को पार्स करने से पहले, navigator.userAgentData को प्राथमिकता दें.

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

अगर मोबाइल या डेस्कटॉप का इस्तेमाल किया जा रहा है, तो बूलियन mobile वैल्यू का इस्तेमाल करें:

const isMobile = navigator.userAgentData.mobile;

userAgentData.brands, brand और version प्रॉपर्टी के साथ ऑब्जेक्ट का एक कलेक्शन है. इसमें, यह बताया जा सकता है कि ब्राउज़र उन ब्रैंड के साथ काम कर सकता है या नहीं. इसे सीधे अरे के तौर पर ऐक्सेस किया जा सकता है. इसके अलावा, some() कॉल का इस्तेमाल करके यह देखा जा सकता है कि कोई खास एंट्री मौजूद है या नहीं:

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
}

अगर आपको ज़्यादा जानकारी और ज़्यादा एंट्रॉपी उपयोगकर्ता-एजेंट वैल्यू में से किसी एक की ज़रूरत है, तो आपको यह वैल्यू देनी होगी और लौटाए गए Promise में नतीजे की जांच करनी होगी:

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

अगर आपको सर्वर-साइड प्रोसेसिंग से क्लाइंट-साइड प्रोसेसिंग पर जाना है, तो इस रणनीति का इस्तेमाल किया जा सकता है. JavaScript एपीआई को एचटीटीपी अनुरोध के हेडर के ऐक्सेस की ज़रूरत नहीं होती. इसलिए, उपयोगकर्ता-एजेंट वैल्यू का किसी भी समय अनुरोध किया जा सकता है.

रणनीति: स्टैटिक सर्वर-साइड हेडर

अगर सर्वर पर User-Agent अनुरोध के हेडर का इस्तेमाल किया जा रहा है और उस डेटा के लिए आपकी ज़रूरतें, आपकी पूरी साइट पर एक जैसी हैं, तो अपनी पसंद के क्लाइंट हिंट को अपने रिस्पॉन्स में स्टैटिक सेट के तौर पर बताया जा सकता है. यह एक आसान तरीका है, क्योंकि आपको आम तौर पर इसे सिर्फ़ एक जगह पर कॉन्फ़िगर करना होता है. उदाहरण के लिए, अगर आपने पहले से ही हेडर जोड़े हुए हैं, तो यह आपके वेब सर्वर कॉन्फ़िगरेशन में हो सकता है. इसके अलावा, अगर आपने अपनी साइट के लिए फ़्रेमवर्क या प्लैटफ़ॉर्म का इस्तेमाल किया है, तो आपके होस्टिंग कॉन्फ़िगरेशन या टॉप लेवल कॉन्फ़िगरेशन में भी यह आपके वेब सर्वर कॉन्फ़िगरेशन में हो सकता है.

अगर उपयोगकर्ता-एजेंट के डेटा के आधार पर दिखाए गए जवाबों में बदलाव या उन्हें पसंद के मुताबिक बनाया जा रहा है, तो इस रणनीति पर विचार करें.

ब्राउज़र या दूसरे क्लाइंट अलग-अलग डिफ़ॉल्ट संकेत दे सकते हैं. इसलिए, अपनी ज़रूरत की हर चीज़ के बारे में बताना एक अच्छा तरीका होता है. भले ही, वह आम तौर पर डिफ़ॉल्ट रूप से ही क्यों न दिया गया हो.

उदाहरण के लिए, Chrome के लिए मौजूदा डिफ़ॉल्ट इस तरह दिखाए जाएंगे:

⬇️ रिस्पॉन्स हेडर

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

अगर आपको भी जवाबों में डिवाइस का मॉडल पाना है, तो आपको यह भेजना होगा:

⬇️ रिस्पॉन्स हेडर

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

इसे सर्वर साइड पर प्रोसेस करते समय, आपको सबसे पहले यह देखना होगा कि मनचाहा Sec-CH-UA हेडर भेज दिया गया है या नहीं. इसके बाद, उपलब्ध न होने पर User-Agent हेडर पार्सिंग पर वापस जाएं.

रणनीति: क्रॉस-ऑरिजिन अनुरोधों को संकेत देने की सुविधा

अगर आपने ऐसे क्रॉस-ऑरिजिन या क्रॉस-साइट सबरिसॉर्स के लिए अनुरोध किया है जिनके अनुरोधों पर उपयोगकर्ता-एजेंट क्लाइंट हिंट भेजने की ज़रूरत है, तो आपको अनुमतियों से जुड़ी नीति का इस्तेमाल करके, साफ़ तौर पर मनचाहे संकेत देने होंगे.

उदाहरण के लिए, मान लें कि https://blog.site, https://cdn.site पर रिसॉर्स होस्ट करता है. ये रिसॉर्स, किसी खास डिवाइस के लिए ऑप्टिमाइज़ किए गए संसाधनों को दिखा सकते हैं. https://blog.site, Sec-CH-UA-Model संकेत मांग सकता है, लेकिन उसे Permissions-Policy हेडर का इस्तेमाल करके साफ़ तौर पर https://cdn.site को अपना प्रतिनिधि बनाना होगा. नीति से कंट्रोल किए जाने वाले संकेतों की सूची, क्लाइंट हिंट इन्फ़्रास्ट्रक्चर ड्राफ़्ट में उपलब्ध है

⬇️ blog.site का जवाब, जिसमें संकेत दिया गया है

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

⬆️ cdn.site पर सबरिसॉर्स के अनुरोध में, दिया गया संकेत शामिल होता है

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

ch-ua रेंज के साथ-साथ, एक से ज़्यादा ऑरिजिन के लिए एक से ज़्यादा संकेत दिए जा सकते हैं:

⬇️ blog.site का जवाब, जिसमें एक से ज़्यादा ऑरिजिन के लिए एक से ज़्यादा संकेत दिए गए हों

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

रणनीति: iframes को संकेत देना

क्रॉस-ऑरिजिन iframe, क्रॉस-ऑरिजिन रिसॉर्स की तरह ही काम करते हैं, लेकिन allow एट्रिब्यूट में उन संकेतों के बारे में बताएं जिन्हें आपको दूसरों को देना है.

⬇️ blog.site का जवाब

Accept-CH: Sec-CH-UA-Model

blog.site के लिए ↪️ एचटीएमएल

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

⬆️ widget.site का अनुरोध

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

iframe में allow एट्रिब्यूट, ऐसे किसी भी Accept-CH हेडर को बदल देगा जो widget.site खुद भेज सकता है. इसलिए, पक्का करें कि आपने वह सभी जानकारी दी हो जो iframe'd साइट को चाहिए.

रणनीति: डाइनैमिक सर्वर साइड संकेत

अगर आपकी साइट पर कुछ ऐसे खास हिस्से हैं जहां आपको मिलने वाले संकेतों की ज़रूरत साइट के बाकी हिस्सों के मुकाबले ज़्यादा है, तो पूरी साइट पर नहीं, बल्कि मांग पर मिलने वाले संकेतों के लिए अनुरोध किया जा सकता है. इसे मैनेज करना ज़्यादा मुश्किल है. हालांकि, अगर आपने हर रूट के हिसाब से पहले से ही अलग-अलग हेडर सेट किए हैं, तो ऐसा करना मुमकिन है.

ध्यान रखें कि Accept-CH हेडर का हर इंस्टेंस, मौजूदा सेट को ओवरराइट कर देगा. इसलिए, अगर हेडर को डाइनैमिक तरीके से सेट किया जा रहा है, तो ऐसे में हर पेज को ज़रूरी संकेतों के पूरे सेट का अनुरोध करना होगा.

उदाहरण के लिए, आपकी साइट पर एक सेक्शन हो सकता है जहां आपको ऐसे आइकॉन और कंट्रोल उपलब्ध कराने हैं जो उपयोगकर्ता के ऑपरेटिंग सिस्टम से मिलते-जुलते हों. इसके लिए, आपको सही सबरिसॉर्स देने के लिए, Sec-CH-UA-Platform-Version को भी शामिल करना पड़ सकता है.

⬇️ /blog के रिस्पॉन्स हेडर

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

⬇️ /app के रिस्पॉन्स हेडर

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

रणनीति: पहले अनुरोध पर सर्वर की ओर से संकेत देना ज़रूरी है

ऐसा भी हो सकता है कि आपको पहले अनुरोध पर, संकेतों के डिफ़ॉल्ट सेट से ज़्यादा की ज़रूरत पड़े. हालांकि, ऐसा बहुत कम होता है, इसलिए पक्का करें कि आपने तर्क की समीक्षा की हो.

पहले अनुरोध का मतलब, उस ब्राउज़िंग सेशन में भेजे गए उस ऑरिजिन के लिए पहला टॉप-लेवल अनुरोध होता है. संकेतों के डिफ़ॉल्ट सेट में मेजर वर्शन के साथ ब्राउज़र का नाम, प्लैटफ़ॉर्म, और मोबाइल इंडिकेटर शामिल होता है. अब सवाल यह है कि क्या आपको पेज लोड होने के दौरान, ज़्यादा डेटा की ज़रूरत है?

पहले अनुरोध पर अतिरिक्त संकेतों के लिए दो विकल्प हैं. सबसे पहले, Critical-CH हेडर का इस्तेमाल किया जा सकता है. यह Accept-CH फ़ॉर्मैट वाला ही होता है, लेकिन ब्राउज़र को यह बताता है कि अगर पहला अनुरोध बिना अहम संकेत के भेजा गया है, तो ब्राउज़र को तुरंत अनुरोध की कोशिश करनी चाहिए.

⬆️ पहला अनुरोध

[With default headers]

⬇️ रिस्पॉन्स हेडर

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

🔃 ब्राउज़र, अतिरिक्त हेडर के साथ शुरुआती अनुरोध को फिर से कोशिश करता है

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

इसकी वजह से, पहले अनुरोध पर फिर से कोशिश करने की ज़िम्मेदारी ऊपर होगी. हालांकि, इसे लागू करने की लागत काफ़ी कम है. अतिरिक्त हेडर भेजें और बाकी काम ब्राउज़र कर देगा.

जिन स्थितियों में आपको पहले पेज के लोड पर अतिरिक्त संकेतों की ज़रूरत होती है उनके लिए, क्लाइंट हिंट का विश्वसनीयता प्रपोज़ल कनेक्शन-लेवल की सेटिंग में संकेत तय करने के लिए एक रूट तय करता है. यह HTTP/2 और HTTP/3 कनेक्शन पर संकेतों के इस शुरुआती पास को चालू करने के लिए TLS 1.3 के लिए ऐप्लिकेशन-लेयर प्रोटोकॉल सेटिंग(ALPS) एक्सटेंशन का इस्तेमाल करता है. यह अब भी काफ़ी शुरुआती चरण में है. हालांकि, अगर आप TLS और कनेक्शन सेटिंग को सक्रिय रूप से मैनेज करते/करती हैं, तो योगदान देने का यह सही समय है.

रणनीति: लेगसी सपोर्ट

आपकी साइट पर ऐसा लेगसी या तीसरे पक्ष का कोड हो सकता है जो navigator.userAgent पर निर्भर करता है. इसमें उपयोगकर्ता-एजेंट स्ट्रिंग के वे हिस्से भी शामिल हैं जिन्हें कम किया जाएगा. लंबे समय के लिए, आपको इसके बराबर navigator.userAgentData कॉल पर स्विच करना होगा. हालांकि, कुछ समय के लिए ही ऐसा नहीं किया जा सकता.

UA-CH रेट्रोफ़िल एक छोटी लाइब्रेरी है. इसकी मदद से, navigator.userAgent को अनुरोध की गई navigator.userAgentData वैल्यू की मदद से बनाई गई नई स्ट्रिंग से ओवरराइट किया जा सकता है.

उदाहरण के लिए, यह कोड एक उपयोगकर्ता-एजेंट स्ट्रिंग जनरेट करेगा, जिसमें "मॉडल" संकेत भी शामिल होगा:

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

नतीजे में मिलने वाली स्ट्रिंग, Pixel 5 मॉडल दिखाएगी, लेकिन अब भी कम किया गया 92.0.0.0 दिखाएगी, क्योंकि 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

अतिरिक्त सहायता

अगर इन रणनीतियों में आपके इस्तेमाल के उदाहरण को शामिल नहीं किया गया है, तो कृपया Privacy-Sandbox-dev-support रेपो में चर्चा करें. इससे हम साथ मिलकर आपकी समस्या के बारे में ज़्यादा जान पाएंगे.

Unsplash पर रिकार्डो रोचा की फ़ोटो