بهبود حریم خصوصی کاربر و تجربه توسعه‌دهنده با User-Agent Client Hints

User-Agent Client Hints یک افزونه جدید برای Client Hints API است که به توسعه‌دهندگان امکان می‌دهد به اطلاعات مربوط به مرورگر کاربر به روشی با حفظ حریم خصوصی و ارگونومیک دسترسی داشته باشند.

Client Hints به توسعه‌دهندگان این امکان را می‌دهد که به‌طور فعال اطلاعات مربوط به دستگاه یا شرایط کاربر را درخواست کنند، به‌جای اینکه نیاز به تجزیه آن از رشته User-Agent (UA) داشته باشند. ارائه این مسیر جایگزین، اولین قدم برای کاهش نهایی جزئیات رشته User-Agent است.

بیاموزید که چگونه قابلیت‌های موجود خود را که به تجزیه رشته User-Agent متکی هستند، به‌روزرسانی کنید تا از User-Agent Client Hints استفاده کنید.

پیشینه

وقتی مرورگرهای وب درخواست‌هایی ارسال می‌کنند، اطلاعاتی در مورد مرورگر و محیط آن ارائه می‌دهند تا سرورها بتوانند تجزیه و تحلیل را فعال کرده و پاسخ را سفارشی کنند. این موضوع در سال ۱۹۹۶ (RFC 1945 برای HTTP/1.0) تعریف شده است، که در آن می‌توانید تعریف اصلی رشته User-Agent را بیابید، که شامل یک مثال است:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

این هدر برای مشخص کردن محصول (مثلاً مرورگر یا کتابخانه) و یک نظر (مثلاً نسخه) به ترتیب اهمیت در نظر گرفته شده بود.

وضعیت رشته‌ی User-Agent

در طول دهه‌های گذشته، این رشته جزئیات اضافی متنوعی در مورد کلاینتی که درخواست را انجام داده است (و همچنین به دلیل سازگاری با نسخه‌های قبلی، اطلاعات نادرستی را نیز جمع‌آوری کرده است) جمع‌آوری کرده است. با نگاه به رشته فعلی User-Agent کروم می‌توانیم این را ببینیم:

Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4076.0 Mobile Safari/537.36

رشته‌ی بالا حاوی اطلاعاتی در مورد سیستم عامل و نسخه کاربر، مدل دستگاه، برند و نسخه کامل مرورگر، سرنخ‌های کافی برای استنباط اینکه این یک مرورگر موبایل است، و همچنین تعدادی ارجاع به مرورگرهای دیگر به دلایل تاریخی است.

ترکیب این پارامترها با تنوع مطلق مقادیر ممکن به این معنی است که رشته User-Agent می‌تواند حاوی اطلاعات کافی باشد تا امکان شناسایی منحصر به فرد کاربران فراهم شود.

رشته‌ی User-Agent موارد استفاده‌ی مشروع زیادی را امکان‌پذیر می‌کند و هدف مهمی را برای توسعه‌دهندگان و صاحبان سایت دنبال می‌کند. با این حال، محافظت از حریم خصوصی کاربران در برابر روش‌های ردیابی مخفی نیز بسیار مهم است و ارسال اطلاعات UA به طور پیش‌فرض خلاف این هدف است.

همچنین نیاز به بهبود سازگاری وب در مورد رشته User-Agent وجود دارد. این رشته بدون ساختار است، بنابراین تجزیه آن منجر به پیچیدگی غیرضروری می‌شود که اغلب علت اشکالات و مشکلات سازگاری سایت است که به کاربران آسیب می‌رساند. این مشکلات همچنین به طور نامتناسبی به کاربران مرورگرهای کمتر رایج آسیب می‌رساند، زیرا ممکن است سایت‌ها در آزمایش پیکربندی آنها شکست خورده باشند.

معرفی نکات جدید کلاینت User-Agent

نکات کاربر-عامل (User-Agent Client Hints) امکان دسترسی به همان اطلاعات را فراهم می‌کنند، اما به روشی که حریم خصوصی را بیشتر حفظ می‌کند، و به نوبه خود مرورگرها را قادر می‌سازد تا در نهایت پیش‌فرض رشته کاربر-عامل مبنی بر پخش همه چیز را کاهش دهند. نکات کاربر مدلی را اجرا می‌کنند که در آن سرور باید از مرورگر مجموعه‌ای از داده‌ها در مورد کلاینت (نکات) را درخواست کند و مرورگر سیاست‌های خود یا پیکربندی کاربر را برای تعیین اینکه چه داده‌هایی بازگردانده شود، اعمال می‌کند. این بدان معناست که به جای افشای تمام اطلاعات کاربر-عامل به طور پیش‌فرض، دسترسی اکنون به روشی صریح و قابل حسابرسی مدیریت می‌شود. توسعه‌دهندگان همچنین از یک API ساده‌تر بهره‌مند می‌شوند - دیگر نیازی به عبارات منظم نیست!

مجموعه فعلی Client Hints در درجه اول قابلیت‌های نمایش و اتصال مرورگر را توصیف می‌کند. می‌توانید جزئیات را در Automating Resource Selection with Client Hints بررسی کنید، اما در اینجا یک مرور سریع در مورد این فرآیند ارائه شده است.

سرور از طریق یک هدر، Client Hint های خاصی را درخواست می‌کند:

⬇️ پاسخ از سرور

Accept-CH: Viewport-Width, Width

یا یک متا تگ:

<meta http-equiv="Accept-CH" content="Viewport-Width, Width" />

سپس مرورگر می‌تواند انتخاب کند که هدرهای زیر را در درخواست‌های بعدی ارسال کند:

⬆️ درخواست بعدی

Viewport-Width: 460
Width: 230

سرور می‌تواند پاسخ‌های خود را تغییر دهد، برای مثال، با ارائه تصاویر با وضوح مناسب.

نکات مربوط به کلاینت عامل کاربر (User-Agent Client Hints) با پیشوند Sec-CH-UA که می‌تواند از طریق هدر پاسخ سرور Accept-CH مشخص شود، طیف وسیعی از ویژگی‌ها را گسترش می‌دهد. برای مشاهده تمام جزئیات، با توضیح‌دهنده شروع کنید و سپس به سراغ پیشنهاد کامل بروید.

نکات مربوط به کلاینت User-Agent از Chromium 89

نکات مربوط به کلاینت User-Agent از نسخه ۸۹ به بعد به طور پیش‌فرض در کروم فعال شده‌اند.

به طور پیش‌فرض، مرورگر برند مرورگر، نسخه اصلی/مهم، پلتفرم و اگر کلاینت یک دستگاه تلفن همراه باشد، یک نشانگر را برمی‌گرداند:

⬆️ همه درخواست‌ها

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"

هدرهای پاسخ و درخواست کاربر-عامل

⬇️ Accept-CH
⬆️ درخواست سربرگ
⬆️ درخواست
مقدار مثال
توضیحات
Sec-CH-UA "Chromium";v="84",
"Google Chrome";v="84"
فهرست برندهای مرورگر و نسخه قابل توجه آنها.
Sec-CH-UA-Mobile ?1 مقداری بولی که نشان می‌دهد آیا مرورگر روی دستگاه تلفن همراه است ( ?1 برای درست) یا خیر ( ?0 برای نادرست).
Sec-CH-UA-Full-Version "84.0.4143.2" [ منسوخ شده ]نسخه کامل برای مرورگر.
Sec-CH-UA-Full-Version-List "Chromium";v="84.0.4143.2",
"Google Chrome";v="84.0.4143.2"
فهرست برندهای مرورگر و نسخه کامل آنها.
Sec-CH-UA-Platform "Android" پلتفرم دستگاه، معمولاً سیستم عامل (OS).
Sec-CH-UA-Platform-Version "10" نسخه مربوط به پلتفرم یا سیستم عامل.
Sec-CH-UA-Arch "arm" معماری زیربنایی دستگاه. اگرچه ممکن است این موضوع ربطی به نمایش صفحه نداشته باشد، اما سایت ممکن است بخواهد دانلودی را ارائه دهد که به طور پیش‌فرض فرمت مناسبی داشته باشد.
Sec-CH-UA-Model "Pixel 3" مدل دستگاه.
Sec-CH-UA-Bitness "64" میزان بیتی بودن معماری زیربنایی (یعنی اندازه یک عدد صحیح یا آدرس حافظه بر حسب بیت)

مثال تبادل

یک نمونه تبادل به این شکل خواهد بود:

⬆️ درخواست اولیه از مرورگر
مرورگر صفحه /downloads را از سایت درخواست می‌کند و User-Agent پیش‌فرض و پایه خود را ارسال می‌کند.

GET /downloads HTTP/1.1
Host: example.site

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Platform: "Android"

⬇️ پاسخ از سرور
سرور صفحه را برمی‌گرداند و علاوه بر آن، نسخه کامل مرورگر و پلتفرم را نیز درخواست می‌کند.

HTTP/1.1 200 OK
Accept-CH: Sec-CH-UA-Full-Version-List

⬆️ درخواست‌های بعدی
مرورگر به سرور اجازه دسترسی به اطلاعات اضافی را می‌دهد و نکات اضافی را در تمام درخواست‌های بعدی ارسال می‌کند.

GET /downloads/app1 HTTP/1.1
Host: example.site

Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"
Sec-CH-UA-Platform: "Android"

رابط برنامه‌نویسی جاوا اسکریپت

در کنار هدرها، می‌توان از طریق navigator.userAgentData در جاوا اسکریپت به User-Agent نیز دسترسی پیدا کرد. اطلاعات هدر پیش‌فرض Sec-CH-UA ، Sec-CH-UA-Mobile و Sec-CH-UA-Platform به ترتیب از طریق ویژگی‌های brands و mobile قابل دسترسی هستند:

// Log the brand data
console.log(navigator.userAgentData.brands);

// output
[
  {
    brand: 'Chromium',
    version: '93',
  },
  {
    brand: 'Google Chrome',
    version: '93',
  },
  {
    brand: ' Not;A Brand',
    version: '99',
  },
];

// Log the mobile indicator
console.log(navigator.userAgentData.mobile);

// output
false;

// Log the platform value
console.log(navigator.userAgentData.platform);

// output
"macOS";

مقادیر اضافی از طریق فراخوانی getHighEntropyValues() قابل دسترسی هستند. اصطلاح "آنتروپی بالا" به آنتروپی اطلاعات اشاره دارد، به عبارت دیگر - میزان اطلاعاتی که این مقادیر در مورد مرورگر کاربر نشان می‌دهند. همانند درخواست هدرهای اضافی، به مرورگر بستگی دارد که چه مقادیری، در صورت وجود، بازگردانده شوند.

// Log the full user-agent data
navigator
  .userAgentData.getHighEntropyValues(
    ["architecture", "model", "bitness", "platformVersion",
     "fullVersionList"])
  .then(ua => { console.log(ua) });

// output
{
   "architecture":"x86",
   "bitness":"64",
   "brands":[
      {
         "brand":" Not A;Brand",
         "version":"99"
      },
      {
         "brand":"Chromium",
         "version":"98"
      },
      {
         "brand":"Google Chrome",
         "version":"98"
      }
   ],
   "fullVersionList":[
      {
         "brand":" Not A;Brand",
         "version":"99.0.0.0"
      },
      {
         "brand":"Chromium",
         "version":"98.0.4738.0"
      },
      {
         "brand":"Google Chrome",
         "version":"98.0.4738.0"
      }
   ],
   "mobile":false,
   "model":"",
   "platformVersion":"12.0.1"
}

نسخه آزمایشی

شما می‌توانید هم هدرها و هم API جاوا اسکریپت را روی دستگاه خودتان در user-agent-client-hints.glitch.me امتحان کنید.

طول عمر و تنظیم مجدد Hint

نکات مشخص شده از طریق هدر Accept-CH برای مدت زمان جلسه مرورگر یا تا زمانی که مجموعه متفاوتی از نکات مشخص شود، ارسال می‌شوند.

یعنی اگر سرور ارسال کند:

⬇️ پاسخ

Accept-CH: Sec-CH-UA-Full-Version-List

سپس مرورگر تا زمان بسته شدن مرورگر، هدر Sec-CH-UA-Full-Version-List را برای تمام درخواست‌های آن سایت ارسال می‌کند.

⬆️ درخواست‌های بعدی

Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"

با این حال، اگر هدر Accept-CH دیگری دریافت شود، آن کاملاً جایگزین نکات فعلی ارسال شده توسط مرورگر خواهد شد.

⬇️ پاسخ

Accept-CH: Sec-CH-UA-Bitness

⬆️ درخواست‌های بعدی

Sec-CH-UA-Platform: "64"

Sec-CH-UA-Full-Version-List که قبلاً درخواست شده بود، ارسال نخواهد شد .

بهتر است هدر Accept-CH را به عنوان مشخص کننده مجموعه کامل نکات مورد نظر برای آن صفحه در نظر بگیرید، به این معنی که مرورگر سپس نکات مشخص شده را برای تمام زیرمنابع موجود در آن صفحه ارسال می‌کند. در حالی که نکات تا پیمایش بعدی ادامه خواهند داشت، سایت نباید به آنها تکیه کند یا فرض کند که تحویل داده می‌شوند.

همچنین می‌توانید با ارسال یک Accept-CH خالی در پاسخ، از این برای پاک کردن مؤثر تمام نکات ارسالی توسط مرورگر استفاده کنید. در نظر داشته باشید که این را در هر جایی که کاربر تنظیمات را تنظیم مجدد می‌کند یا از سایت شما خارج می‌شود، اضافه کنید.

این الگو همچنین با نحوه عملکرد راهنمایی‌ها از طریق برچسب <meta http-equiv="Accept-CH" …> مطابقت دارد. راهنمایی‌های درخواستی فقط به درخواست‌های آغاز شده توسط صفحه ارسال می‌شوند و نه در هیچ ناوبری بعدی.

دامنه اشاره و درخواست‌های بین‌منبعی

به طور پیش‌فرض، Client Hints فقط برای درخواست‌های same-origin ارسال می‌شود. این بدان معناست که اگر در https://example.com درخواست hints خاصی داشته باشید، اما منابعی که می‌خواهید بهینه‌سازی کنید در https://downloads.example.com باشند، هیچ hintی دریافت نخواهند کرد.

برای مجاز کردن راهنمایی‌ها (hints) در درخواست‌های بین مبدایی (cross-origin)، هر راهنمایی و مبدا باید توسط یک هدر Permissions-Policy مشخص شوند. برای اعمال این مورد به User-Agent Client Hint، باید راهنمایی را با حروف کوچک بنویسید و پیشوند sec- را حذف کنید. برای مثال:

⬇️ پاسخ از example.com

Accept-CH: Sec-CH-UA-Platform-Version, DPR
Permissions-Policy: ch-ua-platform-version=(self "downloads.example.com"),
                    ch-dpr=(self "cdn.provider" "img.example.com");

⬆️ درخواست به downloads.example.com

Sec-CH-UA-Platform-Version: "10"

⬆️ درخواست‌ها به cdn.provider یا img.example.com

DPR: 2

کجا از User-Agent Client Hints استفاده کنیم؟

پاسخ سریع این است که شما باید هر موردی را که در آن هدر User-Agent را تجزیه می‌کنید یا از هر یک از فراخوانی‌های جاوا اسکریپت که به همان اطلاعات دسترسی دارند (مثل navigator.userAgent ، navigator.appVersion یا navigator.platform ) استفاده می‌کنید، برای استفاده از User-Agent Client Hints، بازسازی کنید.

با برداشتن یک قدم فراتر، باید نحوه‌ی استفاده از اطلاعات User-Agent را مجدداً بررسی کنید و در صورت امکان آن را با روش‌های دیگر جایگزین کنید. اغلب، می‌توانید با استفاده از بهبود تدریجی، تشخیص ویژگی یا طراحی واکنش‌گرا به همان هدف برسید. مشکل اساسی تکیه بر داده‌های User-Agent این است که شما همیشه یک نگاشت بین ویژگی‌ای که بررسی می‌کنید و رفتاری که قادر به انجام آن است، حفظ می‌کنید. این یک سربار نگهداری است تا اطمینان حاصل شود که تشخیص شما جامع و به‌روز است.

با در نظر گرفتن این نکات، مخزن User-Agent Client Hints برخی از موارد استفاده معتبر برای سایت‌ها را فهرست می‌کند .

چه اتفاقی برای رشته User-Agent می‌افتد؟

هدف این است که با کاهش میزان اطلاعات شناسایی افشا شده توسط رشته User-Agent موجود، امکان ردیابی پنهان در وب به حداقل برسد، در حالی که اختلال بی‌موردی در سایت‌های موجود ایجاد نشود. معرفی User-Agent Client Hints اکنون به شما فرصتی می‌دهد تا قبل از هرگونه تغییری در رشته‌های User-Agent، قابلیت جدید را درک و آزمایش کنید.

در نهایت ، اطلاعات موجود در رشته‌ی User-Agent کاهش می‌یابد، بنابراین فرمت قدیمی را حفظ می‌کند و در عین حال فقط همان اطلاعات مرورگر سطح بالا و نسخه‌های مهم را طبق نکات پیش‌فرض ارائه می‌دهد. در کرومیوم، این تغییر حداقل تا سال ۲۰۲۲ به تعویق افتاده است تا زمان بیشتری برای اکوسیستم فراهم شود تا قابلیت‌های جدید نکات مشتری عامل کاربر را ارزیابی کند.

شما می‌توانید با فعال کردن فلگ about://flags/#reduce-user-agent از کروم ۹۳، نسخه‌ای از این قابلیت را آزمایش کنید (توجه: این فلگ در نسخه‌های کروم ۸۴ تا ۹۲ با نام about://flags/#freeze-user-agent شناخته می‌شد). این کار به دلایل سازگاری، رشته‌ای حاوی ورودی‌های تاریخی، اما با جزئیات پاک‌سازی‌شده، را برمی‌گرداند. برای مثال، چیزی شبیه به:

Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36

تصویر بندانگشتی اثر سرگئی زولکین در Unsplash