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

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

حالة التنفيذ

دعم المتصفح

  • 119
  • 85
  • 65
  • 11.1

المصدر

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

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

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

واجهة برمجة التطبيقات 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 via 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 above 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
طلب إذن الوصول إلى واجهة برمجة التطبيقات للوصول إلى مساحة التخزين في 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 older 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') {
            // Currently not used. See:
      // https://github.com/privacycg/storage-access/issues/149
      return false;
          }
    }

  // By default return false, though should really be caught by one of above.
  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 ولا تحصر SSA بملفات تعريف الارتباط Secure، وبالتالي تكون هذه السمات غير مطلوبة. ننصح بتوضيح السمة SameSite واستخدام ملفات تعريف الارتباط Secure دائمًا.

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

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

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

الطريقة requestStorageAccessFor()

دعم المتصفح

  • 119
  • 119
  • x
  • x

المصدر

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

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

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

دعم المتصفح

  • x
  • x
  • x
  • x

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

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

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

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

المراجع