Storage Access API

การบล็อกคุกกี้ของบุคคลที่สามโดยเบราว์เซอร์ การตั้งค่าของผู้ใช้ และการแบ่งพาร์ติชันพื้นที่เก็บข้อมูลเป็นอุปสรรคต่อเว็บไซต์และบริการที่ต้องอาศัยคุกกี้และพื้นที่เก็บข้อมูลอื่นๆ ในบริบทที่ฝังไว้สำหรับเส้นทางของผู้ใช้ เช่น การตรวจสอบสิทธิ์ Storage Access API (SAA) ช่วยให้ Use Case เหล่านี้ทำงานต่อไปได้ พร้อมทั้งจำกัดการติดตามข้ามเว็บไซต์ให้ได้มากที่สุด

สถานะการติดตั้งใช้งาน

Browser Support

  • Chrome: 119.
  • Edge: 85.
  • Firefox: 65.
  • Safari: 11.1.

Source

Storage Access API พร้อมใช้งานในเบราว์เซอร์หลักทั้งหมด แต่เบราว์เซอร์แต่ละรายการมีความแตกต่างในการติดตั้งใช้งานเล็กน้อย เราได้ไฮไลต์ความแตกต่างเหล่านี้ไว้ในส่วนที่เกี่ยวข้องในโพสต์นี้

เรายังคงดำเนินการแก้ไขปัญหาการบล็อกที่เหลือทั้งหมดก่อนที่จะกำหนดมาตรฐาน API

Storage Access API คืออะไร

Storage Access API เป็น JavaScript API ที่อนุญาตให้ iframe ขอสิทธิ์เข้าถึงพื้นที่เก็บข้อมูลได้เมื่อการตั้งค่าเบราว์เซอร์จะปฏิเสธการเข้าถึง การฝังที่มี Use Case ซึ่งขึ้นอยู่กับการโหลดทรัพยากรข้ามเว็บไซต์สามารถใช้ API เพื่อขอสิทธิ์เข้าถึงจากผู้ใช้ได้ตามความจำเป็น

หากได้รับคำขอพื้นที่เก็บข้อมูล iframe จะมีสิทธิ์เข้าถึงคุกกี้และพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันของตัวเอง ซึ่งจะพร้อมใช้งานเมื่อผู้ใช้เข้าชมเป็นเว็บไซต์ระดับบนสุดด้วย

Storage Access API อนุญาตให้เข้าถึงคุกกี้และพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันที่เฉพาะเจาะจงโดยมีภาระน้อยที่สุดต่อผู้ใช้ปลายทาง ในขณะที่ยังคงป้องกันการเข้าถึงคุกกี้และพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันทั่วไปซึ่งมักใช้สำหรับการติดตามผู้ใช้

กรณีการใช้งาน

การฝังของบุคคลที่สามบางรายการต้องเข้าถึงคุกกี้หรือพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันเพื่อมอบประสบการณ์การใช้งานที่ดีขึ้นแก่ผู้ใช้ ซึ่งเป็นสิ่งที่ใช้ไม่ได้เมื่อมีการจำกัดคุกกี้ของบุคคลที่สามและเปิดใช้การแบ่งพาร์ติชันพื้นที่เก็บข้อมูล

กรณีการใช้งานมีดังนี้

  • วิดเจ็ตการแสดงความคิดเห็นที่ฝังซึ่งต้องใช้รายละเอียดเซสชันการเข้าสู่ระบบ
  • ปุ่ม "ถูกใจ" ของโซเชียลมีเดียซึ่งต้องใช้รายละเอียดเซสชันการเข้าสู่ระบบ
  • เอกสารที่ฝังซึ่งต้องใช้รายละเอียดเซสชันการเข้าสู่ระบบ
  • ประสบการณ์ระดับพรีเมียมที่มอบให้แก่วิดีโอที่ฝัง (เช่น เพื่อไม่ให้แสดงโฆษณาต่อผู้ใช้ที่เข้าสู่ระบบ หรือเพื่อทราบค่ากำหนดของผู้ใช้สำหรับคำบรรยายแทนเสียง หรือเพื่อจำกัดวิดีโอบางประเภท)
  • ระบบการชำระเงินที่ฝังไว้

กรณีการใช้งานเหล่านี้หลายกรณีเกี่ยวข้องกับการคงสิทธิ์เข้าถึงการเข้าสู่ระบบใน iframe ที่ฝัง

กรณีที่ควรใช้ Storage Access API แทน API อื่นๆ

Storage Access API เป็นหนึ่งในทางเลือกแทนการใช้คุกกี้และพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชัน ดังนั้นจึงควรทำความเข้าใจว่าเมื่อใดที่ควรใช้ API นี้เมื่อเทียบกับ API อื่นๆ โดยมีไว้สำหรับกรณีการใช้งานที่ตรงกับเงื่อนไขทั้ง 2 ข้อต่อไปนี้

  • ผู้ใช้จะโต้ตอบกับเนื้อหาที่ฝังไว้ ซึ่งหมายความว่าไม่ใช่ iframe แบบพาสซีฟหรือ iframe ที่ซ่อนอยู่
  • ผู้ใช้ได้เข้าชมต้นทางที่ฝังในบริบทระดับบนสุด ซึ่งหมายความว่าต้นทางนั้นไม่ได้ฝังอยู่ในเว็บไซต์อื่น

มี API อื่นๆ สำหรับกรณีการใช้งานที่หลากหลาย ดังนี้

  • Cookies Having Independent Partitioned State (CHIPS) ช่วยให้นักพัฒนาซอฟต์แวร์เลือกใช้คุกกี้กับพื้นที่เก็บข้อมูล "ที่แบ่งพาร์ติชัน" ได้ โดยมีกล่องเก็บคุกกี้แยกกันสำหรับแต่ละเว็บไซต์ระดับบนสุด ตัวอย่างเช่น วิดเจ็ตแชทบนเว็บของบุคคลที่สามอาจต้องอาศัยการตั้งค่าคุกกี้เพื่อบันทึกข้อมูลเซสชัน ระบบจะบันทึกข้อมูลเซสชันต่อเว็บไซต์ ดังนั้นจึงไม่จำเป็นต้องเข้าถึงคุกกี้ที่วิดเจ็ตตั้งค่าไว้ในเว็บไซต์อื่นๆ ที่มีการฝังวิดเจ็ตด้วย Storage Access API มีประโยชน์เมื่อวิดเจ็ตของบุคคลที่สามที่ฝังไว้ต้องแชร์ข้อมูลเดียวกันในต้นทางต่างๆ (เช่น รายละเอียดเซสชันที่เข้าสู่ระบบหรือค่ากำหนด)
  • การแบ่งพาร์ติชันพื้นที่เก็บข้อมูลเป็นวิธีที่ iframe ข้ามเว็บไซต์ใช้กลไกการจัดเก็บ JavaScript ที่มีอยู่ขณะที่แบ่งพื้นที่เก็บข้อมูลพื้นฐานต่อเว็บไซต์ ซึ่งจะป้องกันไม่ให้การฝังพื้นที่เก็บข้อมูลในเว็บไซต์หนึ่งเข้าถึงได้โดยการฝังเดียวกันในเว็บไซต์อื่นๆ
  • ชุดเว็บไซต์ที่เกี่ยวข้อง (RWS) เป็นวิธีที่องค์กรใช้ประกาศความสัมพันธ์ระหว่างเว็บไซต์ เพื่อให้เบราว์เซอร์อนุญาตการเข้าถึงคุกกี้และพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันแบบจำกัดเพื่อวัตถุประสงค์บางอย่าง เว็บไซต์ยังคงต้องขอสิทธิ์เข้าถึงด้วย Storage Access API แต่สำหรับเว็บไซต์ภายในชุด ระบบจะให้สิทธิ์เข้าถึงได้โดยไม่ต้องมีข้อความแจ้งให้ผู้ใช้ดำเนินการ
  • Federated Credential Management (FedCM) เป็นแนวทางที่รักษาความเป็นส่วนตัวสำหรับบริการระบุตัวตนแบบรวม Storage Access API จัดการการเข้าถึงคุกกี้และพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันหลังการเข้าสู่ระบบ สำหรับบางกรณีการใช้งาน FedCM จะเป็นโซลูชันทางเลือกแทน Storage Access API และอาจเป็นตัวเลือกที่แนะนำเนื่องจากมีข้อความแจ้งของเบราว์เซอร์ที่เน้นการเข้าสู่ระบบมากขึ้น อย่างไรก็ตาม การใช้ FedCM มักต้องมีการเปลี่ยนแปลงโค้ดเพิ่มเติม เช่น เพื่อรองรับปลายทาง HTTP
  • นอกจากนี้ ยังมี API สำหรับการป้องกันการประพฤติมิชอบ ที่เกี่ยวข้องกับโฆษณา และการวัดผล และ Storage Access API ไม่ได้มีไว้เพื่อแก้ไขข้อกังวลเหล่านั้น

ใช้ Storage Access API

Storage Access API มี 2 วิธีที่อิงตาม Promise ดังนี้

นอกจากนี้ยังผสานรวมกับ 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.
    hasAccess = await document.hasStorageAccess();
    if (!hasAccess) {
      // Handle the lack of access (covered later)
    }
  }
  if (hasAccess) {
    // Use the cookies.
  }
}
handleCookieAccessInit();

Storage Access API จะให้สิทธิ์เข้าถึงพื้นที่เก็บข้อมูลแก่เอกสาร iframe หลังจากที่เรียกใช้ requestStorageAccess(), เท่านั้น ดังนั้น hasStorageAccess() อาจแสดงผลเป็นเท็จในตอนแรก เช่น หากผู้ใช้บล็อกคุกกี้ของบุคคลที่สามโดยค่าเริ่มต้น (อย่างไรก็ตาม การตั้งค่าผู้ใช้ที่เฉพาะเจาะจงเว็บไซต์อาจอนุญาตให้เข้าถึงคุกกี้ในเว็บไซต์หนึ่งๆ ได้เช่นกัน แม้ว่าผู้ใช้จะบล็อกคุกกี้ของบุคคลที่สามโดยค่าเริ่มต้นก็ตาม) การเข้าถึงพื้นที่เก็บข้อมูลโดยใช้ API นี้จะยังคงอยู่ในการไปยังส่วนต่างๆ ที่มีต้นทางเดียวกันภายใน 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);

ข้อความแจ้งขอสิทธิ์

เมื่อผู้ใช้คลิกปุ่มเป็นครั้งแรก ข้อความแจ้งของเบราว์เซอร์จะปรากฏขึ้นโดยอัตโนมัติในกรณีส่วนใหญ่ ซึ่งมักจะอยู่ในแถบที่อยู่ ภาพหน้าจอต่อไปนี้ แสดงตัวอย่างข้อความแจ้งของ Chrome แต่เบราว์เซอร์อื่นๆ มี UI ที่คล้ายกัน

ข้อความแจ้งสิทธิ์ Storage Access API ของ Chrome
ข้อความแจ้งขอสิทธิ์ Storage Access API ของ Chrome

เบราว์เซอร์อาจข้ามข้อความแจ้งและให้สิทธิ์โดยอัตโนมัติในบางกรณี

  • หากมีการใช้หน้าเว็บและ iframe ในช่วง 30 วันที่ผ่านมาหลังจากยอมรับข้อความแจ้ง
  • หาก iframe ที่ฝังเป็นส่วนหนึ่งของชุดเว็บไซต์ที่เกี่ยวข้อง
  • หากใช้ FedCM เป็นสัญญาณความน่าเชื่อถือสำหรับการเข้าถึงพื้นที่เก็บข้อมูล
  • ใน Firefox ระบบจะข้ามข้อความแจ้งสำหรับเว็บไซต์ที่รู้จัก (เว็บไซต์ที่คุณโต้ตอบด้วยในระดับบนสุด) ใน 5 ครั้งแรกด้วย

หรือระบบอาจปฏิเสธวิธีการดังกล่าวโดยอัตโนมัติโดยไม่แสดงข้อความแจ้งในบางกรณี

  • หากผู้ใช้ไม่เคยเข้าชมและโต้ตอบกับเว็บไซต์ที่เป็นเจ้าของ iframe ในฐานะเอกสารระดับบนสุด ไม่ใช่ใน iframe ซึ่งหมายความว่า Storage Access API จะมีประโยชน์เฉพาะสำหรับเว็บไซต์ที่ฝังซึ่งผู้ใช้เคยเข้าชมในบริบทของบุคคลที่หนึ่ง
  • หากมีการเรียกใช้เมธอด requestStorageAccess() นอกเหตุการณ์การโต้ตอบของผู้ใช้โดยไม่ได้รับอนุมัติล่วงหน้าสำหรับข้อความแจ้งหลังจากการโต้ตอบ

แม้ว่าระบบจะแจ้งให้ผู้ใช้ทราบในการใช้งานครั้งแรก แต่การเข้าชมครั้งต่อๆ ไปจะสามารถแก้ไข requestStorageAccess() ได้โดยไม่ต้องแจ้งเตือนและไม่ต้องมีการโต้ตอบจากผู้ใช้ใน Chrome และ Firefox โปรดทราบว่า Safari ต้องมีการโต้ตอบจากผู้ใช้เสมอ

เนื่องจากอาจมีการให้สิทธิ์เข้าถึงคุกกี้และพื้นที่เก็บข้อมูลโดยไม่ต้องแจ้งเตือนหรือการโต้ตอบของผู้ใช้ จึงมักเป็นไปได้ที่จะได้รับสิทธิ์เข้าถึงคุกกี้หรือพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันก่อนที่ผู้ใช้จะโต้ตอบในเบราว์เซอร์ที่รองรับฟีเจอร์นี้ (Chrome และ Firefox) โดยการเรียกใช้ requestStorageAccess() เมื่อโหลดหน้าเว็บ ซึ่งอาจช่วยให้คุณเข้าถึงคุกกี้และพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันได้ทันทีและมอบประสบการณ์การใช้งานที่สมบูรณ์ยิ่งขึ้น แม้ว่าผู้ใช้จะยังไม่ได้โต้ตอบกับ iframe ก็ตาม ซึ่งอาจเป็นประสบการณ์การใช้งานที่ดีกว่าในบางสถานการณ์เมื่อเทียบกับการรอการโต้ตอบของผู้ใช้

FedCM เป็นสัญญาณความน่าเชื่อถือสำหรับ SAA

FedCM (Federated Credential Management) เป็น แนวทางที่รักษาความเป็นส่วนตัวสำหรับบริการข้อมูลประจำตัวแบบรวม (เช่น "ลงชื่อเข้าใช้ ด้วย...") ซึ่งไม่ได้อาศัยคุกกี้ของบุคคลที่สามหรือการเปลี่ยนเส้นทางแบบนำทาง

เมื่อผู้ใช้เข้าสู่ระบบฝ่ายที่ต้องอาศัยข้อมูล (RP) ซึ่งมีเนื้อหาที่ฝังจากผู้ให้บริการข้อมูลประจำตัว (IdP) บุคคลที่สามที่มี FedCM เนื้อหา IdP ที่ฝังจะได้รับการเข้าถึงพื้นที่เก็บข้อมูลสำหรับคุกกี้ระดับบนสุดของตัวเองที่ไม่ได้แบ่งพาร์ติชันโดยอัตโนมัติ หากต้องการ เปิดใช้การเข้าถึงพื้นที่เก็บข้อมูลอัตโนมัติด้วย FedCM คุณต้องมีคุณสมบัติตรงตามเงื่อนไขต่อไปนี้

  • การตรวจสอบสิทธิ์ FedCM (สถานะการลงชื่อเข้าใช้ของผู้ใช้) ต้องใช้งานอยู่
  • RP เลือกใช้โดยตั้งค่าสิทธิ์ identity-credentials-get เช่น
<iframe src="https://idp.example" allow="identity-credentials-get"></iframe>

เช่น idp.example iframe ฝังอยู่ใน rp.example เมื่อผู้ใช้ เข้าสู่ระบบด้วย FedCM idp.example iframe จะขอสิทธิ์เข้าถึงพื้นที่เก็บข้อมูลสำหรับคุกกี้ระดับบนสุดของตัวเองได้

rp.example จะเรียกใช้ FedCM เพื่อบันทึกการเข้าสู่ระบบของผู้ใช้ด้วยผู้ให้บริการข้อมูลประจำตัว idp.example

// The user will be asked to grant FedCM permission.
const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/fedcm.json',
      clientId: '123',
    }],
  },
});

หลังจากที่ผู้ใช้เข้าสู่ระบบแล้ว IdP จะเรียกใช้ requestStorageAccess() จากภายใน iframe ของ idp.example ได้ ตราบใดที่ RP อนุญาตอย่างชัดแจ้งด้วยนโยบายสิทธิ์ ระบบจะให้สิทธิ์เข้าถึงพื้นที่เก็บข้อมูลแก่การฝังสำหรับคุกกี้ระดับบนสุดของตัวเองโดยอัตโนมัติ โดยไม่ต้องให้ผู้ใช้เปิดใช้งานหรือแสดงข้อความแจ้งขอสิทธิ์อีก

// Make this call within the embedded IdP iframe:

// No user gesture is needed, and the storage access will be auto-granted.
await document.requestStorageAccess();

// This returns `true`.
const hasAccess = await document.hasStorageAccess();

ระบบจะให้สิทธิ์โดยอัตโนมัติก็ต่อเมื่อผู้ใช้ลงชื่อเข้าใช้ด้วย FedCM เมื่อการตรวจสอบสิทธิ์ไม่ทำงานแล้ว ข้อกำหนด SAA มาตรฐาน จะมีผลในการให้สิทธิ์เข้าถึงพื้นที่เก็บข้อมูล

คุณขอสิทธิ์เข้าถึง Local Storage ที่ไม่ได้แบ่งพาร์ติชันได้โดยส่งพารามิเตอร์ types ไปยังการเรียกใช้ requestStorageAccess เช่น หากต้องการขอสิทธิ์เข้าถึง Local Storage ที่ไม่ได้แบ่งพาร์ติชัน คุณสามารถเรียกใช้ requestStorageAccess({localStorage: true}) ได้

หากเปิดใช้คุกกี้ของบุคคลที่สาม วิธีนี้จะให้สิทธิ์เข้าถึงโดยไม่ต้องให้ผู้ใช้เปิดใช้งาน หรือแสดงข้อความแจ้งขอสิทธิ์ใดๆ หากผู้ใช้ปิดใช้คุกกี้ของบุคคลที่สาม ระบบจะต้องแจ้งให้ผู้ใช้ทราบก่อนจึงจะให้สิทธิ์เข้าถึงพื้นที่เก็บข้อมูลได้

โฟลว์ชาร์ตสำหรับ Storage Access API ซึ่งแสดงวิธีรับสิทธิ์เข้าถึงพื้นที่เก็บข้อมูลที่ไม่ใช่คุกกี้
ขั้นตอนการขอสิทธิ์เข้าถึงพื้นที่เก็บข้อมูลที่ไม่ใช่คุกกี้

ก่อนอื่น ให้ตรวจสอบว่าเบราว์เซอร์มีสิทธิ์เข้าถึงพื้นที่เก็บข้อมูลอยู่แล้วหรือไม่ โดยทำดังนี้

async function hasCookieAccess(){
  // Check if Storage Access API is supported
  if (!document.requestStorageAccess) {
    // Storage Access API is not supported, so we assume it's an older browser that doesn't partition storage.
    throw new Error("requestStorageAccess is not supported")
  }

  // Check if access has already been granted or if the user has 3-party cookies enabled
  return document.hasStorageAccess();
}

หากเปิดใช้คุกกี้ของบุคคลที่สาม ให้ขอสิทธิ์เข้าถึงพื้นที่เก็บข้อมูลโดยทำดังนี้

// Request storage access and return the storage handle
async function requestStorageHandle(){
// You can request for multiple types of non-cookie storage
// at once, or request for all of them with all:true
return document.requestStorageAccess({all:true});
}

หากมีการบล็อกคุกกี้ของบุคคลที่สาม (เช่น ในโหมดไม่ระบุตัวตน) ให้ตรวจสอบสิทธิ์การค้นหาเพื่อ พิจารณาว่าจำเป็นต้องมีข้อความแจ้งผู้ใช้หรือไม่ navigator.permissions.query({name: 'storage-access'}) สถานะสิทธิ์อาจมีค่าต่อไปนี้

  • granted ผู้ใช้ได้ให้สิทธิ์เข้าถึงแล้ว เรียกใช้ requestStorageAccess เพื่อรับ สิทธิ์เข้าถึงพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันโดยไม่ต้องแจ้งให้ผู้ใช้ดำเนินการเพิ่มเติม
  • prompt ผู้ใช้ยังไม่ได้ให้สิทธิ์เข้าถึง ตั้งค่าเครื่องมือฟังการคลิกและเรียกใช้ requestStorageAccess อีกครั้งหลังจากการโต้ตอบของผู้ใช้
  • error ไม่รองรับสิทธิ์นี้ เมื่อรองรับ Storage Access API แล้ว ระบบก็น่าจะรองรับสิทธิ์นี้ด้วย
// Returns `granted`, or `prompt`; or throws an error if storage-access
// permission is not supported
async function getStorageAccessPermission(){
  // Check the storage-access permission
  // Wrap this in a try/catch for browsers that support the
  // Storage Access API but not this permission check
    return navigator.permissions.query({name: 'storage-access'});
}

คุณสามารถใช้ขั้นตอนทั้งหมดในการจัดการพื้นที่เก็บข้อมูลที่ไม่ได้แบ่งพาร์ติชันคุกกี้ได้ดังนี้

async function getStorageHandle() {
    // Check if the user has 3-party cookie access
    if (await hasCookieAccess()) {
    // If the user has access, requestStorageAccess() will resolve automatically
        return requestStorageHandle();
    }

    // If the browser blocks third party cookies, check if the user has
    // accepted the prompt and granted access. If they have,
    // requestStorageAccess() will resolve automatically
    const permission = await getStorageAccessPermission();
    if (permission == 'granted') { // User has seen prompt and granted access
        return requestStorageHandle();
    }

    // Wait for user activation to prompt the user again
    // (or put your silent failure logic here instead)
    return new Promise((resolve, reject) => {
        document.querySelector('#myButton').addEventListener(e => {
            requestStorageHandle().then(resolve, reject);
        })
    })
}

// Use your storage
getStorageHandle().then(handle=>{
    handle.indexedDB.open(...);
}).catch(() => {
    // If the promise is rejected, you can use regular partitioned storage
    indexedDB.open(...);
})

การโหลดครั้งต่อๆ ไปด้วยส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูล

ส่วนหัว Storage Access เป็นวิธีที่แนะนำและมีประสิทธิภาพมากกว่าในการเปิดใช้การโหลด เนื้อหาที่ฝัง รวมถึงทรัพยากรที่ไม่ใช่ iframe ฟีเจอร์นี้พร้อมใช้งาน ตั้งแต่ Chrome 133 เป็นต้นไป เมื่อมีส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูล เบราว์เซอร์จะจดจำได้เมื่อ ผู้ใช้ได้ให้สิทธิ์ storage-access แก่ต้นทางของบุคคลที่สามแล้ว ในบริบทปัจจุบัน และจะโหลดทรัพยากรที่มีสิทธิ์เข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน ในการเข้าชมครั้งต่อๆ ไป

ขั้นตอนของส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูล

เมื่อใช้ส่วนหัว Storage Access การเข้าชมหน้าเว็บต่อๆ ไปจะทริกเกอร์โฟลว์ต่อไปนี้

  1. ผู้ใช้เคยเข้าชม website.example ที่ฝังทรัพยากร calendar.example และให้สิทธิ์ storage-access ด้วยการเรียกใช้ document.requestStorageAccess()
  2. ผู้ใช้เข้าชม website.example ที่มีทรัพยากร calendar.example ฝังอยู่อีกครั้ง คำขอนี้ยังไม่มีสิทธิ์เข้าถึงคุกกี้เหมือนเดิม อย่างไรก็ตาม ผู้ใช้ได้ให้storage-accessสิทธิ์ไว้ก่อนหน้านี้แล้ว และ การดึงข้อมูลมีส่วนหัว Sec-Fetch-Storage-Access: inactive เพื่อระบุว่า การเข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชันพร้อมใช้งานแต่ไม่ได้เปิดใช้งาน
  3. เซิร์ฟเวอร์ calendar.example ตอบกลับด้วยส่วนหัว Activate-Storage-Access: retry; allowed-origin='<origin>' (ในกรณีนี้ <origin> จะเป็น https://website.example) เพื่อ ระบุว่าการดึงข้อมูลทรัพยากรต้องใช้คุกกี้ที่ไม่ได้แบ่งพาร์ติชันซึ่งมี สิทธิ์ storage-access
  4. เบราว์เซอร์จะลองส่งคำขออีกครั้ง โดยครั้งนี้จะรวมคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน (เปิดใช้งานสิทธิ์ storage-access สำหรับการดึงข้อมูลนี้และการดึงข้อมูล ครั้งต่อๆ ไป)
  5. calendar.example เซิร์ฟเวอร์จะตอบกลับด้วยเนื้อหา iframe ที่ปรับเปลี่ยนในแบบของคุณ การตอบกลับมีส่วนหัว Activate-Storage-Access: load เพื่อระบุว่า เบราว์เซอร์ควรโหลดเนื้อหาโดยเปิดใช้storage-accessสิทธิ์ (กล่าวคือ โหลดโดยมีการเข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน เหมือนกับว่ามีการเรียกใช้ document.requestStorageAccess())
  6. User Agent จะโหลดเนื้อหา iframe โดยมีการเข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน โดยใช้สิทธิ์ storage-access หลังจากขั้นตอนนี้ วิดเจ็ตจะทำงานได้ตามที่คาดไว้
โฟลว์ชาร์ตแสดงโฟลว์ของส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูล
แผนภาพโฟลว์ของส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูล

ใช้ส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูล

ตารางต่อไปนี้แสดงรายการส่วนหัวการเข้าถึงพื้นที่เก็บข้อมูล

Flow ส่วนหัว ค่า คำอธิบาย
ส่งคำขอ Sec-Fetch-Storage-Access
หมายเหตุ: เบราว์เซอร์จะส่งส่วนหัวนี้โดยอัตโนมัติในคำขอข้ามเว็บไซต์ ที่รวมข้อมูลเข้าสู่ระบบ (เช่น new Request('request.example', { credentials: 'include' });)
none Embed ไม่มีสิทธิ์เข้าถึงพื้นที่เก็บข้อมูล
inactive Embed มีสิทธิ์ แต่ไม่ได้ใช้สิทธิ์ดังกล่าว
คำขอต้องมีส่วนหัว Origin ด้วย
active การฝังมีการเข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชัน
การตอบกลับ Activate-Storage-Access load สั่งให้เบราว์เซอร์ให้สิทธิ์เข้าถึงคุกกี้ที่ไม่ได้แบ่งพาร์ติชันแก่ผู้ฝังสำหรับทรัพยากรที่ขอ
การรวมส่วนหัวนี้เทียบเท่ากับการเรียก document.requestStorageAccess() หากได้รับstorage-access สิทธิ์ แล้ว ซึ่งหมายความว่าจะไม่มีข้อความแจ้งเพิ่มเติมแสดงต่อผู้ใช้
retry สั่งให้เบราว์เซอร์เปิดใช้งานสิทธิ์เข้าถึงพื้นที่เก็บข้อมูล แล้วลองส่งคำขออีกครั้ง
allowed-origin <origin> ระบุต้นทางที่ได้รับอนุญาตให้เริ่มคำขอที่ต้องใช้ข้อมูลเข้าสู่ระบบ (เช่น https://site.example หรือ *)

ตัวอย่างเช่น คุณสามารถใช้ส่วนหัว Storage Access เพื่อโหลดรูปภาพจาก บุคคลที่สามได้

  // On the client side
  <img src="https://server.example/image">

ในกรณีนี้ server.example ควรใช้ตรรกะต่อไปนี้ในฝั่งเซิร์ฟเวอร์

  app.get('/image', (req, res) => {
  const storageAccessHeader = req.headers['sec-fetch-storage-access'];

  if (storageAccessHeader === 'inactive') {
    // The user needs to grant permission, trigger a prompt

    // Check if the requesting origin is allowed
    // to send credentialed requests to this server.
    // Assuming the `validate_origin(origin)` method is previously defined:
    if (!validate_origin(req.headers.origin)) {
      res.status(401).send(req.headers.origin +
        ' is not allowed to send credentialed requests to this server.');
      return;
    }
    // 'retry' header value indicates that the content load request should be re-sent after the user has granted permissions
    res.set('Activate-Storage-Access', `retry; allowed-origin='${req.headers.origin}'`);
    res.status(401).send('This resource requires storage access. Please grant permission.');
  } else if (storageAccessHeader === 'active') {
    // User has granted permission, proceed with access
    res.set('Activate-Storage-Access', 'load');
    // Include the actual iframe content here
    res.send('This is the content that requires cookie access.');
  } else {
    // Handle other cases (e.g., 'Sec-Fetch-Storage-Access': 'none')
  }
});

การสาธิต Storage Access API จะฝังเนื้อหาของบุคคลที่สาม (รวมถึงรูปภาพที่ไม่ใช่ 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 ในการเรียก API
  • allow-same-origin ต้องอนุญาตให้เข้าถึงคุกกี้และพื้นที่เก็บข้อมูลอื่นๆ ที่มีต้นทางเดียวกัน

เช่น

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

หากต้องการเข้าถึงด้วย Storage Access API ใน Chrome ต้องตั้งค่าคุกกี้ข้ามเว็บไซต์ด้วยแอตทริบิวต์ 2 รายการต่อไปนี้

  • SameSite=None - ซึ่งจำเป็นต้องใช้เพื่อทำเครื่องหมายคุกกี้เป็นแบบข้ามเว็บไซต์
  • Secure ซึ่งช่วยให้มั่นใจได้ว่าจะเข้าถึงได้เฉพาะคุกกี้ที่เว็บไซต์ HTTPS ตั้งค่าไว้เท่านั้น

ใน Firefox และ Safari ค่าเริ่มต้นของคุกกี้คือ SameSite=None และไม่ได้จำกัด SAA ไว้ที่คุกกี้ Secure ดังนั้นจึงไม่จำเป็นต้องใช้แอตทริบิวต์เหล่านี้ ขอแนะนำให้ระบุแอตทริบิวต์ SameSite อย่างชัดเจนและใช้คุกกี้ Secure เสมอ

การเข้าถึงหน้าเว็บระดับบนสุด

Storage Access API มีไว้เพื่อเปิดใช้การเข้าถึงคุกกี้ของบุคคลที่สามภายใน iframe ที่ฝัง

นอกจากนี้ ยังมีกรณีการใช้งานอื่นๆ เมื่อหน้าเว็บระดับบนสุดต้องเข้าถึงคุกกี้ของบุคคลที่สาม เช่น รูปภาพหรือสคริปต์ที่คุกกี้จำกัด ซึ่งเจ้าของเว็บไซต์อาจต้องการรวมไว้ในเอกสารระดับบนสุดโดยตรงแทนที่จะรวมไว้ใน iframe Chrome ได้เสนอส่วนขยายสำหรับ Storage Access API เพื่อจัดการกับ Use Case นี้ ซึ่งจะเพิ่มเมธอดrequestStorageAccessFor()

requestStorageAccessFor() วิธี

Browser Support

  • Chrome: 119.
  • Edge: 119.
  • Firefox: not supported.
  • Safari: not supported.

Source

requestStorageAccessFor() ทำงานคล้ายกับ requestStorageAccess() แต่ใช้กับทรัพยากรระดับบนสุด ใช้ได้เฉพาะกับเว็บไซต์ภายในชุดเว็บไซต์ที่เกี่ยวข้องเพื่อป้องกันการให้สิทธิ์เข้าถึงคุกกี้ของบุคคลที่สามโดยทั่วไป

ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีใช้ requestStorageAccessFor() ได้ที่ชุดเว็บไซต์ที่เกี่ยวข้อง: คู่มือสำหรับนักพัฒนาซอฟต์แวร์

top-level-storage-access การค้นหาสิทธิ์

Browser Support

  • Chrome: 113.
  • Edge: 113.
  • Firefox: not supported.
  • Safari: not supported.

สิทธิ์ top-level-storage-access จะคล้ายกับสิทธิ์ storage-access โดยใช้เพื่อตรวจสอบว่าสามารถให้สิทธิ์เข้าถึง requestStorageAccessFor() ได้หรือไม่

Storage Access API แตกต่างออกไปอย่างไรเมื่อใช้กับ RWS

เมื่อใช้ชุดเว็บไซต์ที่เกี่ยวข้องกับ Storage Access API จะมีฟีเจอร์เพิ่มเติมบางอย่างตามรายละเอียดในตารางต่อไปนี้

ไม่มี RWS พร้อม RWS
ต้องมีการกระทำของผู้ใช้เพื่อเริ่มคำขอสิทธิ์เข้าถึงพื้นที่เก็บข้อมูล
กำหนดให้ผู้ใช้ต้องไปที่ต้นทางของพื้นที่เก็บข้อมูลที่ขอในบริบทระดับบนสุดก่อนที่จะให้สิทธิ์เข้าถึง
คุณข้ามข้อความแจ้งสำหรับผู้ใช้ครั้งแรกได้
requestStorageAccess ไม่จำเป็นต้องเรียกใช้หากได้รับสิทธิ์เข้าถึงก่อนหน้านี้แล้ว
ให้สิทธิ์เข้าถึงโดเมนอื่นๆ ในชุดเว็บไซต์ที่เกี่ยวข้องโดยอัตโนมัติ
รองรับ requestStorageAccessFor สำหรับการเข้าถึงหน้าเว็บระดับบนสุด
ความแตกต่างระหว่างการใช้ Storage Access API โดยไม่มีและมีชุดเว็บไซต์ที่เกี่ยวข้อง

การสาธิต: การตั้งค่าและการเข้าถึงคุกกี้

การสาธิตต่อไปนี้แสดงวิธีเข้าถึงคุกกี้ที่คุณตั้งค่าไว้ในหน้าจอแรกของการสาธิตในเฟรมที่ฝังในเว็บไซต์ที่ 2 ของการสาธิต

storage-access-api-demo.glitch.me

การสาธิตต้องใช้เบราว์เซอร์ที่ปิดใช้คุกกี้ของบุคคลที่สาม

  • Chrome 118 ขึ้นไปที่มีการตั้งค่าchrome://flags/#test-third-party-cookie-phaseoutและรีสตาร์ทเบราว์เซอร์แล้ว
  • Firefox
  • Safari

การสาธิต: การตั้งค่าพื้นที่เก็บข้อมูลในเครื่อง

การสาธิตต่อไปนี้แสดงวิธีเข้าถึง Broadcast Channel ที่ไม่ได้แบ่งพาร์ติชันจาก iframe ของบุคคลที่สามโดยใช้ Storage Access API

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

การสาธิตต้องใช้ Chrome 125 ขึ้นไปโดยเปิดใช้ค่าสถานะ test-third-party-cookie-phaseout

แหล่งข้อมูล