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

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

حالة التنفيذ

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

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

المصدر

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

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

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

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

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

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

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

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

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

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

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

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

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

  • سيتفاعل المستخدم مع المحتوى المضمن - أي أنه ليس إطار 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

تتضمّن واجهة برمجة التطبيقات 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، ولكن تتضمّن المتصفّحات الأخرى واجهة مستخدم مشابهة:

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

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

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

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

  • إذا لم يسبق للمستخدم زيارة الموقع الإلكتروني الذي يملك إطار iframe والتفاعل معه كمستند من المستوى الأعلى، وليس في إطار iframe. وهذا يعني أنّ واجهة Storage Access API لا تكون مفيدة إلا للمواقع الإلكترونية المضمّنة التي سبق للمستخدمين زيارتها في سياق الطرف الأول.
  • إذا تمّ استدعاء طريقة 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 API.
  • allow-scripts مطلوب للسماح باستخدام JavaScript لطلب واجهة برمجة التطبيقات.
  • يجب استخدام allow-same-origin للسماح بالوصول إلى ملفات تعريف الارتباط من المصدر نفسه ومساحة التخزين الأخرى.

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

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

للوصول إلى ملفات تعريف الارتباط على جميع المواقع الإلكترونية باستخدام واجهة برمجة التطبيقات Storage Access API في 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 عند استخدامها مع RWS؟

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

بدون RWS مع 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.

الموارد