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

अपनी साइट को यूज़र-एजेंट स्ट्रिंग पर निर्भर रहने से, नए यूज़र-एजेंट क्लाइंट हिंट पर माइग्रेट करने की रणनीतियां.

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

इस लेख में, यूज़र-एजेंट डेटा के ऐक्सेस की ऑडिटिंग करने और यूज़र-एजेंट स्ट्रिंग के इस्तेमाल को यूज़र-एजेंट क्लाइंट हिंट पर माइग्रेट करने का तरीका बताया गया है.

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

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

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

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

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

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

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

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

  • Sec-CH-UA: ब्राउज़र का नाम और मुख्य/ज़रूरी वर्शन
  • Sec-CH-UA-Mobile: मोबाइल डिवाइस की जानकारी देने वाली बूलियन वैल्यू
  • Sec-CH-UA-Platform: ऑपरेटिंग सिस्टम का नाम
    • ध्यान दें कि इसे स्पेसिफ़िकेशन में अपडेट कर दिया गया है. यह बदलाव जल्द ही Chrome और Chromium पर आधारित अन्य ब्राउज़र में दिखेगा.

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

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

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

रणनीति: मांग पर क्लाइंट-साइड 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 API को एचटीटीपी अनुरोध के हेडर के ऐक्सेस की ज़रूरत नहीं होती. इसलिए, उपयोगकर्ता-एजेंट वैल्यू के लिए किसी भी समय अनुरोध किया जा सकता है.

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

अगर सर्वर पर 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 को हिंट देना

क्रॉस-ऑरिजिन iframes, क्रॉस-ऑरिजिन रिसॉर्स की तरह ही काम करते हैं. हालांकि, आपको 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 वाली साइट के लिए ज़रूरी सभी जानकारी दी हो.

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

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

यहां ध्यान देने वाली खास बात यह है कि 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

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

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

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

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

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

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

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 पर मौजूद, रिकार्डो रोचा की फ़ोटो