واجهة برمجة التطبيقات Storage Access API

يشكّل حظر ملفات تعريف الارتباط التابعة لجهات خارجية من خلال المتصفّحات وإعدادات المستخدم وتقسيم مساحة التخزين تحديًا للمواقع الإلكترونية والخدمات التي تعتمد على ملفات تعريف الارتباط ومساحة التخزين الأخرى في السياقات المضمّنة، وذلك لتجارب المستخدمين، مثل المصادقة. تسمح واجهة Storage Access API (SAA) بمواصلة العمل مع الحد من تتبُّع إجراءات المستخدم على مواقع إلكترونية متعددة بقدر الإمكان.

حالة التنفيذ

دعم المتصفح

  • Chrome: 119.
  • الحافة: 85.
  • Firefox: 65
  • ‫Safari: 11.1

المصدر

تتوفّر Storage Access API في جميع المتصفحات الرئيسية، ولكن هناك اختلافات طفيفة في التنفيذ بين المتصفحات. وقد تم إبراز هذه الاختلافات في الأقسام المعنيّة في هذه المشاركة.

نواصل العمل على حلّ جميع مشاكل الحظر المتبقية، قبل توحيد واجهة برمجة التطبيقات.

ما هي واجهة برمجة التطبيقات Storage Access؟

واجهة برمجة التطبيقات Storage Access هي واجهة برمجة تطبيقات JavaScript تسمح لإطارات iframe بطلب أذونات الوصول إلى مساحة التخزين في حال رفض إعدادات المتصفّح الوصول إلى المحتوى. إنّ عمليات التضمين التي تتضمّن حالات استخدام تعتمد على تحميل موارد من مواقع إلكترونية متعددة يمكن أن تستخدم واجهة برمجة التطبيقات لطلب إذن الوصول من المستخدم حسب الحاجة.

في حال الموافقة على طلب التخزين، سيتمكّن إطار iframe من الوصول إلى ملفات تعريف الارتباط ومساحة التخزين غير المقسَّمة، والتي تكون متاحة أيضًا عند انتقال المستخدمين إلى الموقع الإلكتروني من المستوى الأعلى.

تسمح واجهة برمجة التطبيقات Storage Access API بتوفير وصول محدد غير مقسّم إلى ملفات تعريف الارتباط وسعة التخزين، مع مراعاة الحد الأدنى من الأعباء التي تقع على عاتق المستخدم النهائي، مع منع الوصول العام غير المقسّم إلى ملفات تعريف الارتباط وسعة التخزين، كما يُستخدَم غالبًا لتتبُّع المستخدم.

حالات الاستخدام

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

وتشمل حالات الاستخدام ما يلي:

  • أدوات التعليق المضمّنة التي تتطلّب تفاصيل جلسة تسجيل الدخول
  • أزرار "أعجبني" على وسائل التواصل الاجتماعي التي تتطلّب تفاصيل جلسة تسجيل الدخول
  • المستندات المضمَّنة التي تتطلب تفاصيل جلسة تسجيل الدخول
  • تجربة مميزة مقدَّمة من خلال فيديو مضمّن (على سبيل المثال، لعدم عرض إعلانات للمستخدمين الذين سجّلوا دخولهم أو لمعرفة ما يفضّله المستخدم بشأن مقاطع الترجمة والشرح أو لفرض قيود على أنواع معيّنة من الفيديوهات).
  • أنظمة الدفع المضمّنة

وتتضمن العديد من حالات الاستخدام هذه استمرار تسجيل الدخول في إطارات iframe المضمّنة.

حالات استخدام Storage Access API على واجهات برمجة التطبيقات الأخرى

واجهة برمجة التطبيقات Storage Access API هي أحد البدائل لاستخدام ملفّات تعريف الارتباط ومساحة التخزين غير المقسّمة، لذا من المهمّ معرفة الحالات التي يجب فيها استخدام هذه الواجهة مقارنةً بالواجهات الأخرى. وهي مخصّصة لحالات الاستخدام التي ينطبق فيها ما يلي:

  • سيتفاعل المستخدم مع المحتوى المضمن - أي أنه ليس إطار iframe سلبيًا أو إطار iframe مخفيًا.
  • إذا زار المستخدم المصدر المضمّن في سياق أعلى مستوى، أي عندما لا يكون هذا المصدر مضمّنًا في موقع إلكتروني آخر

هناك واجهات برمجة تطبيقات بديلة لمجموعة متنوعة من حالات الاستخدام:

  • تسمح ملفات تعريف الارتباط ذات الحالة المقسَّمة المستقلّة (CHIPS) للمطوّرين بتفعيل ملف تعريف الارتباط ليكون "مقسمًا". تخزين، مع وعاء منفصل لملفات تعريف الارتباط لكل موقع إلكتروني من المستوى الأعلى. على سبيل المثال، قد تعتمد أداة دردشة الويب التابعة لجهة خارجية على إعداد ملف تعريف ارتباط لحفظ معلومات الجلسة. يتم حفظ معلومات الجلسات لكل موقع إلكتروني، وبالتالي لا يلزم الوصول إلى ملف تعريف الارتباط الذي تم ضبطه من خلال التطبيق المصغّر على المواقع الإلكترونية الأخرى التي تم تضمينها أيضًا. تكون واجهة Storage Access API مفيدة عندما تعتمد أداة خارجية مضمَّنة على مشاركة المعلومات نفسها بين مصادر مختلفة (على سبيل المثال، تفاصيل الجلسة التي تم تسجيل الدخول إليها أو الإعدادات المفضَّلة).
  • إنّ تقسيم مساحة التخزين يتيح لإطارات iframe في مواقع إلكترونية متعددة استخدام آليات تخزين JavaScript الحالية أثناء تقسيم مساحة التخزين الأساسية لكل موقع إلكتروني. وهذا يمنع الوصول إلى التخزين المضمّن في موقع ويب واحد بواسطة التضمين نفسه على مواقع الويب الأخرى.
  • مجموعات المواقع الإلكترونية ذات الصلة (RWS) هي طريقة تتيح للمؤسسة الإفصاح عن العلاقات بين المواقع الإلكترونية، حتى تسمح المتصفّحات بوصول محدود غير مقسّم إلى ملفّات تعريف الارتباط ومساحة التخزين لأغراض محدّدة. ستظل المواقع بحاجة إلى طلب الوصول باستخدام واجهة برمجة التطبيقات Storage Access، ولكن بالنسبة إلى المواقع الإلكترونية داخل المجموعة، يمكن منح الإذن بالوصول بدون طلب المستخدم.
  • إدارة بيانات الاعتماد الموحّدة (FedCM) هي أسلوب للحفاظ على الخصوصية لخدمات الهوية الموحّدة. تتيح واجهة برمجة التطبيقات Storage Access API إمكانية الوصول إلى ملفات تعريف الارتباط غير المقسَّمة ومساحة التخزين بعد تسجيل الدخول. بالنسبة إلى بعض حالات الاستخدام، يوفّر FedCM حلاً بديلاً لواجهة برمجة تطبيقات Storage Access، وقد يفضَّل استخدامه لأنّه يتضمّن طلبات أكثر تركّز على تسجيل الدخول في المتصفِّح. ومع ذلك، يتطلب استخدام FedCM عادةً إجراء تغييرات إضافية على الرمز البرمجي، مثل دعم نقاط نهاية HTTP.
  • تتوفر أيضًا واجهات برمجة تطبيقات مكافحة الاحتيال وذات صلة بالإعلانات والقياس، وليس الغرض من Storage Access API معالجة هذه المشاكل.

استخدام واجهة برمجة التطبيقات Storage Access API

هناك طريقتان متاحتان في Storage Access API:

وهي تتكامل أيضًا مع Permissions API. يتيح لك ذلك التحقّق من حالة إذن الوصول إلى مساحة التخزين في سياق تابع لجهة خارجية، ما يشير إلى ما إذا كان سيتم منح الاتصال برقم "document.requestStorageAccess()" تلقائيًا:

استخدام طريقة hasStorageAccess()

عند تحميل موقع إلكتروني لأول مرة، يمكنه استخدام الطريقة hasStorageAccess() للتحقّق مما إذا كان الوصول إلى ملفات تعريف الارتباط التابعة لجهات خارجية قد سبق وتم منحه إمكانية الوصول إليها.

// Set a hasAccess boolean variable which defaults to false.
let hasAccess = false;

async function handleCookieAccessInit() {
  if (!document.hasStorageAccess) {
    // Storage Access API is not supported so best we can do is
    // hope it's an older browser that doesn't block 3P cookies.
    hasAccess = true;
  } else {
    // Check whether access has been granted using the Storage Access API.
    // Note on page load this will always be false initially so we could be
    // skipped in this example, but including for completeness for when this
    // is not so obvious.
    hasAccess = await document.hasStorageAccess();
    if (!hasAccess) {
      // Handle the lack of access (covered later)
    }
  }
  if (hasAccess) {
    // Use the cookies.
  }
}
handleCookieAccessInit();

لا يتم منح إذن الوصول إلى مساحة التخزين إلا لمستند iframe بعد طلب requestStorageAccess(),، لذا ستعرض hasStorageAccess() دائمًا القيمة false في البداية، ما لم يكن قد تم منح إذن الوصول لمستند آخر من المصدر نفسه في إطار iframe نفسه. يتم الاحتفاظ بالمنحة في عمليات التنقل من المصدر نفسه داخل إطار iframe، خاصةً للسماح بإعادة التحميل بعد منح إذن الوصول إلى الصفحات التي تتطلّب وجود ملفات تعريف الارتباط في الطلب الأولي لمستند HTML.

استخدام requestStorageAccess()

إذا لم يتمكن إطار iframe من الوصول، فقد يحتاج إلى طلب الوصول باستخدام طريقة requestStorageAccess():

if (!hasAccess) {
  try {
    await document.requestStorageAccess();
  } catch (err) {
    // Access was not granted and it may be gated behind an interaction
    return;
  }
}

في المرة الأولى التي يتم فيها طلب ذلك، قد يحتاج المستخدم إلى الموافقة على هذا الوصول من خلال إشعار من المتصفّح، وبعد ذلك سيتم حلّ الوعد أو رفضه، ما يؤدي إلى حدوث استثناء في حال استخدام await.

لمنع إساءة الاستخدام، لن يتم عرض طلب المتصفِّح هذا إلا بعد تفاعل المستخدم. لهذا السبب، يجب استدعاء requestStorageAccess() في البداية من خلال معالِج أحداث ينشطه المستخدم، وليس على الفور أثناء تحميل إطار iframe:

async function doClick() {

  // Only do this extra check if access hasn't already been given
  // based on the hasAccess variable.
  if (!hasAccess) {
    try {
      await document.requestStorageAccess();
      hasAccess = true; // Can assume this was true if requestStorageAccess() did not reject.
    } catch (err) {
      // Access was not granted.
      return;
    }
  }

  if (hasAccess) {
    // Use the cookies
  }
}

document.querySelector('#my-button').addEventListener('click', doClick);

إذا كنت بحاجة إلى استخدام التخزين المحلي بدلاً من ملفات تعريف الارتباط، يمكنك إجراء ما يلي:

let handle = null;

async function doClick() {
  if (!handle) {
    try {
      handle = await document.requestStorageAccess({localStorage: true});
    } catch (err) {
      // Access was not granted.
      return;
    }
  }

  // Use handle to access unpartitioned local storage.
  handle.localStorage.setItem('foo', 'bar');
}

document.querySelector('#my-button').addEventListener('click', doClick);

الطلبات المتعلقة بالأذونات

عندما ينقر المستخدم على الزر لأول مرة، سيظهر مطالبة المتصفح تظهر تلقائيًا، وعادةً في شريط العناوين. لقطة الشاشة التالية مثالاً على طلب من Chrome، ولكن هناك متصفحات أخرى تحتوي على واجهة مستخدم مشابهة:

طلب إذن واجهة برمجة التطبيقات للوصول إلى مساحة التخزين في Chrome
طلب إذن واجهة برمجة التطبيقات Storage Access API في Chrome

قد يتخطّى المتصفّح الطلب ويتم توفير الإذن تلقائيًا في حالات معيّنة:

  • إذا تم استخدام الصفحة وإطار iframe خلال آخر 30 يومًا بعد قبول الطلب.
  • إذا كان إطار iframe المضمّن جزءًا من مجموعة مواقع إلكترونية ذات صلة.
  • في Firefox، يتم أيضًا تخطي الطلب لمواقع الويب المعروفة (تلك التي تفاعلت معها في المستوى الأعلى) في المحاولات الخمس الأولى.

بدلاً من ذلك، قد يتم رفض الطريقة تلقائيًا بدون عرض الطلب في حالات معيّنة:

  • إذا لم يسبق أن زار المستخدم الموقع الإلكتروني الذي يملك إطار iframe كمستند مستوى أعلى، ولم يتفاعل معه من قبل، وليس في إطار iframe. وهذا يعني أنّ واجهة برمجة التطبيقات Storage Access مفيدة فقط للمواقع الإلكترونية المضمّنة التي زارها المستخدمون سابقًا في سياق الطرف الأول.
  • في حال استدعاء طريقة requestStorageAccess() خارج حدث تفاعل المستخدم بدون الحصول على موافقة مسبقة على الطلب بعد تفاعل المستخدم.

على الرغم من أنّه سيتمّ توجيه طلب إلى المستخدم عند الاستخدام الأوّلي، يمكن أن تؤدي الزيارات اللاحقة إلى حلّ مشكلة requestStorageAccess() بدون طلب وبدون الحاجة إلى تفاعل المستخدم في Chrome وFirefox. يُرجى العِلم أنّ متصفّح Safari يتطلّب دائمًا تفاعل المستخدم.

ونظرًا لأنه قد يتم منح إذن الوصول إلى ملفات تعريف الارتباط وسعة التخزين بدون طلب أو تفاعل من المستخدم، فمن الممكن في كثير من الأحيان الحصول على وصول غير مقسّم إلى ملفات تعريف الارتباط أو مساحة التخزين قبل تفاعل المستخدم على المتصفحات التي تتوافق مع هذا الإعداد (Chrome وFirefox) من خلال طلب requestStorageAccess() عند تحميل الصفحة. وقد يتيح لك ذلك الوصول إلى ملفات تعريف الارتباط ومساحة التخزين غير المقسَّمة على الفور وتوفير تجربة أكثر اكتمالاً، حتى قبل تفاعل المستخدم مع إطار iframe. يمكن أن يكون هذا تجربة مستخدم أفضل في بعض المواقف من انتظار تفاعل المستخدم.

استخدام طلب الإذن storage-access

للتحقّق مما إذا كان من الممكن منح إذن الوصول بدون تفاعل المستخدم، يمكنك التحقّق من حالة إذن "storage-access" وإجراء طلب "requestStoreAccess()" في وقت مبكر فقط في حال عدم الحاجة إلى اتّخاذ أي إجراء، بدلاً من طلب الإذن بالوصول وتعذُّر إكماله عندما يكون التفاعل مطلوبًا.

ويتيح لك ذلك أيضًا التعامل مع احتياجك إلى طلب في البداية من خلال عرض محتوى مختلف، مثل زر تسجيل الدخول.

يضيف الرمز التالي عملية التحقّق من الإذن storage-access إلى المثال السابق:

// Set a hasAccess boolean variable which defaults to false except for
// browsers which don't support the API - where we assume
// such browsers also don't block third-party cookies.
let hasAccess = false;

async function hasCookieAccess() {
  // Check if Storage Access API is supported
  if (!document.requestStorageAccess) {
    // Storage Access API is not supported so best we can do is
    // hope it's an older browser that doesn't block 3P cookies.
    return true;
  }

  // Check if access has already been granted
  if (await document.hasStorageAccess()) {
    return true;
  }

  // Check the storage-access permission
  // Wrap this in a try/catch for browsers that support the
  // Storage Access API but not this permission check
  // (e.g. Safari and earlier versions of Firefox).
  let permission;
  try {
    permission = await navigator.permissions.query(
      {name: 'storage-access'}
    );
  } catch (error) {
    // storage-access permission not supported. Assume no cookie access.
    return false;
  }

    if (permission) {
    if (permission.state === 'granted') {
      // Permission has previously been granted so can just call
      // requestStorageAccess() without a user interaction and
      // it will resolve automatically.
      try {
        await document.requestStorageAccess();
        return true;
      } catch (error) {
        // This shouldn't really fail if access is granted, but return false
        // if it does.
        return false;
      }
    } else if (permission.state === 'prompt') {
      // Need to call requestStorageAccess() after a user interaction
      // (potentially with a prompt). Can't do anything further here,
      // so handle this in the click handler.
      return false;
          } else if (permission.state === 'denied') {
            // Not used: see https://github.com/privacycg/storage-access/issues/149
      return false;
          }
    }

  // By default return false, though should really be caught by earlier tests.
  return false;
}

async function handleCookieAccessInit() {
  hasAccess = await hasCookieAccess();

  if (hasAccess) {
    // Use the cookies.
  }
}

handleCookieAccessInit();

إطارات iframe في وضع الحماية

عند استخدام واجهة برمجة التطبيقات Storage Access API في إطارات iframe في وضع الحماية، يجب الحصول على أذونات وضع الحماية التالية:

  • يجب توفير allow-storage-access-by-user-activation للسماح بالوصول إلى واجهة برمجة التطبيقات Storage Access.
  • allow-scripts مطلوب للسماح باستخدام JavaScript لطلب واجهة برمجة التطبيقات.
  • يكون allow-same-origin مطلوبًا للسماح بالوصول إلى ملفات تعريف الارتباط ذات المصدر نفسه ومساحة التخزين الأخرى.

على سبيل المثال:

<iframe sandbox="allow-storage-access-by-user-activation
                 allow-scripts
                 allow-same-origin"
        src="..."></iframe>

للوصول إلى ملفات تعريف الارتباط على مواقع إلكترونية متعددة باستخدام واجهة برمجة التطبيقات Storage Access في Chrome، يجب ضبط السمتَين التاليتين:

  • SameSite=None - وهي مطلوبة لوضع علامة على ملفّ تعريف الارتباط بأنّه يؤدّي إلى مواقع إلكترونية متعدّدة
  • Secure: يضمن هذا الإجراء فقط إمكانية الوصول إلى ملفات تعريف الارتباط التي تم ضبطها من خلال المواقع الإلكترونية التي تستخدم بروتوكول HTTPS.

في Firefox وSafari، تكون ملفات تعريف الارتباط تلقائيًا من النوع SameSite=None ولا تقيّد ميزة SAA بملفات تعريف الارتباط من النوع Secure، لذا فإنّ هذه السمات غير مطلوبة. ننصح بتوضيح السمة SameSite واستخدام ملفات تعريف الارتباط Secure دائمًا.

الوصول إلى الصفحة من المستوى الأعلى

تم تصميم واجهة Storage Access API لإتاحة الوصول إلى ملفات تعريف الارتباط التابعة لجهات خارجية في إطارات iframe المضمَّنة.

هناك أيضًا حالات استخدام أخرى عندما تتطلّب الصفحة ذات المستوى الأعلى الوصول إلى ملفات تعريف الارتباط التابعة لجهات خارجية. على سبيل المثال، الصور أو النصوص البرمجية التي يتم حظرها بواسطة ملفات تعريف الارتباط، والتي قد يريد مالكو المواقع الإلكترونية تضمينها مباشرةً في مستند المستوى الأعلى بدلاً من تضمينها في إطار iframe. لمعالجة حالة الاستخدام هذه، اقترح Chrome إضافة إلى واجهة برمجة التطبيقات Storage Access API، ما أدّى إلى إضافة طريقة requestStorageAccessFor().

الطريقة requestStorageAccessFor()

دعم المتصفح

  • Chrome: 119.
  • ‫Edge: 119
  • Firefox: غير مدعوم.
  • Safari: غير متاح.

المصدر

تعمل طريقة requestStorageAccessFor() بطريقة مشابهة لـ requestStorageAccess() ولكن مع الموارد ذات المستوى الأعلى. ويمكن استخدامها فقط للمواقع الإلكترونية ضمن مجموعة مواقع إلكترونية ذات صلة لمنع منح إذن الوصول العام إلى ملفات تعريف الارتباط التابعة لجهات خارجية.

للحصول على مزيد من التفاصيل حول كيفية استخدام requestStorageAccessFor()، يُرجى الاطّلاع على مجموعات المواقع الإلكترونية ذات الصلة: دليل المطوِّر.

طلب الإذن "top-level-storage-access"

توافق المتصفّح

  • Chrome: غير متاح.
  • Edge: غير متوافقة
  • Firefox: غير مدعوم.
  • Safari: غير متاح.

على غرار إذن storage-access، هناك إذن top-level-storage-access للتحقّق مما إذا كان يمكن منح الإذن بالوصول إلى requestStorageAccessFor().

ما هي أوجه الاختلاف بين واجهة برمجة التطبيقات Storage Access API عند استخدامها مع RWS؟

عند استخدام "مجموعات المواقع الإلكترونية المرتبطة" مع واجهة برمجة التطبيقات Storage Access، تتوفّر بعض الإمكانات الإضافية كما هو موضّح في الجدول التالي:

بدون ميزة "الاستجابة السريعة للطلبات" مع RWS
يجب استخدام إيماءة المستخدم لبدء طلب الوصول إلى مساحة التخزين.
على المستخدم الانتقال إلى مصدر مساحة التخزين المطلوب في سياق من المستوى الأعلى قبل منح إذن الوصول.
يمكن تخطّي طلب المستخدم لأول مرة
لا يلزم الاتصال بـ "requestStorageAccess" إذا تم منح إذن الوصول سابقًا
منح الإذن بالوصول تلقائيًا إلى نطاقات أخرى في موقع إلكتروني ذي صلة
تتيح requestStorageAccessFor للوصول إلى الصفحة ذات المستوى الأعلى
الاختلافات بين استخدام Storage Access API بدون مجموعات المواقع الإلكترونية المرتبطة واستخدامها

العرض التوضيحي: تعيين ملفات تعريف الارتباط والوصول إليها

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

storage-access-api-demo.glitch.me

يتطلّب العرض التوضيحي استخدام متصفّح تم إيقاف ملفات تعريف الارتباط التابعة لجهات خارجية فيه:

  • الإصدار 118 من Chrome أو الإصدارات الأحدث مع ضبط العلامة chrome://flags/#test-third-party-cookie-phaseout وإعادة تشغيل المتصفّح.
  • Firefox
  • Safari

عرض توضيحي: ضبط إعدادات التخزين المحلي

يوضِّح العرض التوضيحي التالي كيفية الوصول إلى قنوات البث غير المقسَّمة من إطار iframe تابع لجهة خارجية باستخدام واجهة برمجة التطبيقات Storage Access API:

https://saa-beyond-cookies.glitch.me/

يتطلّب العرض التوضيحي الإصدار 125 من Chrome أو إصدارًا أحدث مع تفعيل العلامة test-third-party-cookie-phaseout.

الموارد