إضافة عناوين إضافية لطلب HTTP

تحتوي طلبات HTTP على عناوين مثل User-Agent أو Content-Type. بالإضافة إلى الرؤوس التي تعلقها browsers، قد تضيف تطبيقات Android رؤوسًا إضافية، مثل Cookie أو Referrer من خلال ملف EXTRA_HEADERS Intent extra. لدواعٍ أمنية، يصوّر Chrome بعض الرؤوس الإضافية استنادًا إلى كيفية إطلاق النية ومكان إطلاقها.

تتطلب الطلبات المشتركة المصدر طبقة إضافية من الأمان، لأنّ العميل والخادم لا يملكهما الطرف نفسه. يتناول هذا الدليل إطلاق هذه الطلبات من خلال Chrome علامات التبويب المخصّصة، أي النوى التي يتم إطلاقها من التطبيقات التي تفتح عنوان URL في علامة تبويب المتصفّح. حتى الإصدار Chrome 83، كان بإمكان المطوّرين إضافة أي عناوين عند فتح علامة تبويب مخصّصة. بدءًا من الإصدار 83، بدأ Chrome في فلترة جميع الرؤوس التي مصدرها مختلف باستثناء الرؤوس المُدرَجة في القائمة الموافَق عليها، لأنّ الرؤوس غير المُدرَجة في القائمة الموافَق عليها كانت تشكل خطرًا على الأمان. اعتبارًا من الإصدار 86 من Chrome، أصبح من الممكن إرفاق رؤوس غير مدرَجة في القائمة المعتمَدة بطلبات المصدر المختلف، عندما يكون الخادم والعميل مرتبطَين باستخدام رابط مادة عرض رقمية. تم تلخيص هذا السلوك في الجدول التالي:

إصدار Chrome عناوين CORS المسموح بها
قبل الإصدار 83 من Chrome مُدرَج بالموافقة، غير مُدرَج في قائمة الموافقة
من الإصدار 83 من Chrome إلى الإصدار 85 من Chrome مُدرَجة في القائمة الموافَق عليها
من الإصدار 86 من Chrome فصاعدًا مُدرَجة بالموافقة أو غير موافَق عليها عند إعداد رابط إلى مواد العرض الرقمية

الجدول 1: فلترة عناوين CORS غير المُدرَجة في القائمة الموافَق عليها

توضّح هذه المقالة كيفية إعداد اتصال متحقَّق منه بين الخادم والعميل واستخدام ذلك لإرسال عناوين http مُدرجة في قائمة الموافقة بالإضافة إلى عناوين http غير معتمَدة. يمكنك الانتقال إلى إضافة رؤوس إضافية إلى أهداف علامات التبويب المخصّصة للاطّلاع على الرمز.

الخلفية

عناوين طلبات CORS المُدرَجة في القائمة الموافَق عليها مقابل غير المُدرَجة في القائمة الموافَق عليها

تسمح سياسة مشاركة الموارد المتعدّدة المصادر (CORS) لتطبيق ويب من مصدر واحد بطلب موارد من مصدر مختلف. يتم الاحتفاظ بقائمة العناوين المتوافقة مع سياسة CORS في معيار HTML. في الجدول التالي، يظهر مثال على العناوين المُدرَجة في القائمة الموافَق عليها:

Header الوصف
accept-language تعلن عن لغات طبيعية يفهمها العميل
لغة المحتوى وصف اللغة المخصّصة للجمهور الحالي
نوع المحتوى تشير إلى نوع الوسائط الخاص بالمورد

الجدول 2: مثال على رؤوس CORS المُدرَجة في القائمة الموافَق عليها

تُعدّ العناوين المُدرَجة في القائمة الموافَق عليها آمنة لأنّها لا تحتوي على معلومات حساسة للمستخدمين، ومن غير المرجّح أن تتسبب في تنفيذ الخادم لعمليات قد تؤدي إلى إلحاق الضرر.

تظهر أمثلة على العناوين غير المُدرَجة في القائمة المعتمَدة في الجدول التالي:

Header الوصف
رمز الحامل المميز مصادقة العميل على خادم
الأصل يشير إلى أصل الطلب
كعكة محلاة يحتوي على ملفات تعريف ارتباط ضبطها الخادم

الجدول 3: أمثلة على عناوين CORS غير المعتمدة.

لا يوصي معيار HTML بإرفاق عناوين غير مؤهلة بطلبات CORS، وتفترض الخوادم أن الطلبات الواردة من مصادر متعددة تحتوي فقط على عناوين ضمن قائمة موافَق عليها. إنّ إرسال العناوين غير المدرَجة في قائمة الموافقة من النطاقات المتعددة المصادر يسمح للتطبيقات الضارّة التابعة لجهات خارجية بإنشاء عناوين تسيء استخدام ملفات تعريف الارتباط الخاصة بالمستخدم والتي يخزِّنها Chrome (أو متصفّح آخر) ويرفقها بالطلبات. يمكن أن تؤدي ملفات تعريف الارتباط إلى مصادقة معاملات الخادم الضارّة التي لا يمكن إجراؤها بخلاف ذلك.

إرفاق عناوين CORS المُدرَجة في القائمة المعتمَدة بطلبات علامات التبويب المخصّصة

علامات التبويب المخصّصة هي طريقة خاصة لفتح صفحات الويب في علامة تبويب مخصّصة في المتصفّح. يمكن إنشاء طلبات مناقشة مخصّصة باستخدام CustomTabsIntent.Builder(). يمكنك أيضًا إرفاق رؤوس بهذه النوايا باستخدام Bundle مع العلامة Browser.EXTRA_HEADERS:

CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();

Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");   
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);

intent.launchUrl(Activity.this, Uri.parse("http://www.google.com"));

يمكننا في أي وقت إرفاق العناوين المُعتمَدة بطلبات CORS في علامات التبويب المخصّصة. ومع ذلك، يعمل Chrome على فلترة العناوين غير المدرَجة في القائمة تلقائيًا. على الرغم من أنّ المتصفحات الأخرى قد تختلف في سلوكها، يجب أن يتوقّع المطوّرون أن يتم حظر العناوين غير المُدرَجة في القائمة المعتمَدة بشكل عام.

إنّ الطريقة المسموح بها لتضمين العناوين غير المُدرَجة في القائمة المعتمَدة في علامات التبويب المخصّصة هي التحقّق أولاً من الاتصال من مصدر مختلف باستخدام رابط وصول رقمي. يوضِّح القسم التالي كيفية إعداد هذه العناصر وإطلاق نية علامات تبويب مخصّصة باستخدام الرؤوس المطلوبة.

إضافة رؤوس إضافية إلى أهداف علامات التبويب المخصّصة

للسماح بتمرير العناوين غير المدرَجة في القائمة المسموح بها من خلال "روابط وعناصر إعلانية حسب نية العميل" المخصّصة، من الضروري إعداد رابط أصل رقمي بين تطبيق Android وتطبيق الويب بهدف التأكّد من أنّ المؤلف يملك كلا التطبيقين.

اتّبِع الدليل الرسمي لإعداد رابط إلى مواد العرض الرقمية. بالنسبة إلى علاقة الرابط، استخدِم "delegate_permission/common.use_as_origin"" الذي يشير إلى أن كلا التطبيقين ينتميان إلى المصدر نفسه بعد التحقق من الرابط.

إنشاء نية علامة تبويب مخصّصة باستخدام رؤوس إضافية

تتوفّر طرق متعدّدة لإنشاء نية علامات التبويب المخصّصة. يمكنك استخدام أداة الإنشاء المتاحة في androidX من خلال إضافة المكتبة إلى العناصر الاعتمادية للإنشاء:

MULTI_LINE_CODE_PLACEHOLDER_1

أنشئ النية وأضِف رؤوسًا إضافية:

MULTI_LINE_CODE_PLACEHOLDER_2

يتم استخدام اتصال "علامات التبويب المخصّصة" لإعداد CustomTabsSession بين التطبيق وعلامة تبويب Chrome. نحتاج إلى الجلسة للتحقّق من أنّ التطبيق وتطبيق الويب ينتميان إلى المصدر نفسه. لا يتم إثبات الهوية إلّا إذا تم إعداد روابط مواد العرض الرقمية بشكلٍ صحيح.

ننصحك بالاتصال على CustomTabsClient.warmup(). ويسمح هذا الإذن لتطبيق المتصفّح بالتحضير المُسبَق في الخلفية وتسريع عملية فتح عنوان URL.

MULTI_LINE_CODE_PLACEHOLDER_3

إعداد دالة استدعاء تنشئ النية بعد التحقّق منها

تم تمرير CustomTabsCallback إلى الجلسة. لقد أعددنا onRelationshipValidationResult() لتشغيل CustomTabsIntent الذي تم إنشاؤه سابقًا بعد نجاح عملية التحقّق من المصدر.

MULTI_LINE_CODE_PLACEHOLDER_4

ربط اتصال خدمة علامات التبويب المخصّصة

يؤدي ربط الخدمة إلى تشغيل الخدمة وسيتم استدعاء onCustomTabsServiceConnected() للاتصال في النهاية. لا تنسَ إلغاء ربط الخدمة بشكلٍ مناسب. يتم الربط وفك الربط بشكل شائع في طريقتَي onStart() وonStop() لمراحل النشاط.

// Bind the custom tabs service connection.
// Call this in onStart()
CustomTabsClient.bindCustomTabsService(this,
    CustomTabsClient.getPackageName(MainActivity.this, null), connection);

// …
// Unbind the custom tabs service.
// Call this in onStop().
unbindService(connection);

رمز التطبيق التجريبي

يمكنك الاطّلاع على مزيد من التفاصيل حول خدمة "علامات التبويب المخصّصة" هنا. يمكنك الاطّلاع على مستودع GitHub الخاص بتطبيق android-browser-helper للحصول على مثال لتطبيق صالح.

ملخّص

يوضّح هذا الدليل كيفية إضافة رؤوس عشوائية إلى طلبات CORS لعلامات التبويب المخصّصة. يمكن إرفاق العناوين المدرَجة في القائمة التي تمت الموافقة عليها بكل طلبات CORS لعلامات التبويب المخصصة. وبشكل عام، تُعتبر العناوين غير المُدرَجة في القائمة المعتمَدة غير آمنة في طلبات CORS، وفلترتها Chrome تلقائيًا. ولا يُسمح بإرفاقها إلا للعملاء والخوادم من المصدر نفسه، والتي تم إثبات ملكيتها من خلال رابط مادة عرض رقمية.