מדריך למתחילים: הטמעת נפח אחסון משותף וצבירה פרטית

המסמך הזה הוא מדריך למתחילים לשימוש ב'אחסון משותף' וב'פרטי' צבירה. חשוב להבין את שני ממשקי ה-API, כי התכונה 'אחסון משותף'. שומרת את הערכים ו'צבירה פרטית' יוצרת את הדוחות המצטברים.

קהל היעד: ספקי טכנולוגיות פרסום וספקי מדידה.

נסה את ההדגמה

כדאי לנסות את ההדגמה בשידור חי. פועלים לפי השלבים בהוראות ההדגמה כדי להפעיל את ממשקי ה-API של ארגז החול לפרטיות. מתבצעת פתיחה של Chrome כלי הפיתוח עוזרים להמחיש את התוצאות של תרחישים שונים לדוגמה. תרחישים לדוגמה זמינה בהדגמה:

  • צבירת נתונים פרטית
    • מדידה של היקף החשיפה למשתמשים ייחודיים
    • מדידה של מידע דמוגרפי
    • מדידת תדירות של K+
  • שימוש כללי
    • מדידת אירוע שמעביר את העכבר מעל פריט בתוך פריימים מגודרים
    • ניווט ברמה העליונה
    • שליטה במקומות שבהם צדדים שלישיים יכולים לכתוב

איך להציג את נפח האחסון המשותף

כדי לראות מה מאוחסן באחסון המשותף, צריך להשתמש בכלי הפיתוח ל-Chrome. הנתונים המאוחסנים יכולים אפשר למצוא את Application -> Shared Storage.

הצגת הנתונים שמאוחסנים ב-Shared Storage באמצעות כלי הפיתוח ל-Chrome.

צפייה בדוחות של צבירת נתונים פרטית

כדי להציג את הדוחות המצטברים שנשלחו, עוברים אל chrome://private-aggregation-internals כשמצב ניפוי הבאגים מופעל, הדוח נשלחת באופן מיידי (ללא עיכוב) אל [[YOUR_ORIGIN]]/.well-known/private-aggregation/debug/report-shared-storage וכן הדוח עיכוב הזמן שיישלח אל [[YOUR_ORIGIN]]/.well-known/private-aggregation/report-shared-storage.

כדי להפעיל ניפוי באגים, פועלים לפי ההוראות שבמאמר ניפוי באגים. .

צפייה בדוחות בכתובת chrome://private-aggregation-internals.

Shared Storage API

כדי למנוע מעקב באתרים שונים, דפדפנים התחילו לחלק את כל סוגי המחיצות אחסון, כולל אחסון מקומי, קובצי Cookie וכו'. אבל יש תרחישים לדוגמה במקומות שבהם נדרש אחסון לא מחולק. ה-Shared Storage API מספק גישת כתיבה בלתי מוגבלת באתרים שונים ברמה העליונה תוך שמירה על הפרטיות גישת קריאה.

האחסון המשותף מוגבל למקור ההקשר (הקוראים של sharedStorage).

לנפח האחסון המשותף יש מגבלת קיבולת לכל מקור, וכל רשומה מוגבלת ל- מספר תווים מקסימלי. אם מגיעים למגבלה, לא מזינים עוד קלט . מגבלות אחסון הנתונים מפורטות בקטע נפח אחסון משותף. הודעת הסבר.

הפעלת נפח אחסון משותף

טכנולוגיות פרסום יכולות לכתוב לאחסון משותף באמצעות JavaScript או כותרות תגובה. קריאה מאחסון משותף מתרחשת רק בתוך JavaScript מבודד שנקראת worklet.

  • באמצעות JavaScript טכנולוגיות הפרסום יכולות לבצע פונקציות ספציפיות של Shared Storage כמו הגדרה, צירוף ומחיקה של ערכים מחוץ ל-JavaScript מודול worklet. עם זאת, פונקציות כמו קריאת הנתונים של Shared Storage וביצוע של יש לבצע צבירת נתונים פרטית באמצעות worklet של JavaScript. אפשר למצוא שיטות שאפשר להשתמש בהן מחוץ ל-worklet של JavaScript ב- שטח API מוצע – מחוץ worklet.

    אפשר למצוא את ה-methods שבהן נעשה שימוש ב-worklet במהלך פעולה ב- שטח API מוצע – worklet.

  • שימוש בכותרות תגובה

    בדומה ל-JavaScript, יש רק פונקציות ספציפיות כמו הגדרה, צירוף, ולמחוק ערכים באחסון משותף באמצעות כותרות תגובה. שפת תרגום עבודה עם Shared Storage בכותרת תגובה, Shared-Storage-Writable: ?1 צריך לכלול אותו בכותרת הבקשה.

    כדי ליזום בקשה מהלקוח, מריצים את הקוד הבא, בהתאם השיטה שבחרתם:

    • שימוש ב-fetch()
        fetch("https://a.example/path/for/updates", {sharedStorageWritable: true});
    
    • שימוש בתג iframe או img
        <iframe src="https://a.example/path/for/updates" sharedstoragewritable></iframe>
    
    • שימוש במאפיין IDL עם תג iframe או img
        let iframe = document.getElementById("my-iframe");
        iframe.sharedStorageWritable = true;
        iframe.src = "https://a.example/path/for/updates";
    

מידע נוסף זמין בקטע אחסון משותף: תגובה כותרות.

כתיבה לאחסון משותף

כדי לכתוב באחסון המשותף, יש לקרוא ל-sharedStorage.set() מבפנים או מבחוץ worklet של JavaScript. אם נשלחת קריאה מחוץ ל-worklet, הנתונים נכתבים אל המקור של הקשר הגלישה שממנו בוצעה השיחה. אם מתקבלת שיחה מ: בתוך ה-worklet, הנתונים נכתבים למקור של הקשר הגלישה שטען את ה-worklet. למפתחות שהוגדרו יש תאריך תפוגה של 30 ימים מהעדכון האחרון.

השדה ignoreIfPresent הוא אופציונלי. אם הוא קיים ומוגדר ל-true, המפתח לא מתעדכן, אם הוא כבר קיים. תפוגת המפתח מתחדשת ל-30 יום מתאריך הקריאה set(), גם אם המפתח לא מעודכן.

אם מתבצעת גישה לאחסון המשותף כמה פעמים באותה טעינת דף עם אותה , הערך של המפתח יוחלף. כדאי להשתמש sharedStorage.append() אם המפתח צריך לשמור על הערך הקודם.

  • באמצעות JavaScript

    מחוץ ל-worklet:

    window.sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.set('myKey', 'myValue2', { ignoreIfPresent: true });
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.set('myKey', 'myValue2', { ignoreIfPresent: false });
    // Shared Storage: {'myKey': 'myValue2'}
    

    באופן דומה, בתוך ה-worklet:

    sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    
  • שימוש בכותרות תגובה

    אפשר גם לכתוב באחסון משותף באמצעות כותרות תגובה. כדי לעשות את זה, משתמשים Shared-Storage-Write בכותרת התשובה יחד עם הטקסט הבא פקודות:

    Shared-Storage-Write : set;key="myKey";value="myValue";ignore_if_present
    
    Shared-Storage-Write : set;key="myKey";value="myValue";ignore_if_present=?0
    

    אם יש כמה פריטים, אפשר להפריד ביניהם באמצעות פסיקים ואפשר לשלב אותם עם set, append, delete ו-clear.

    Shared-Storage-Write :
    set;key="hello";value="world";ignore_if_present, set;key="good";value="bye"
    

צירוף ערך

אפשר להוסיף ערך למפתח קיים באמצעות שיטת ההוספה. אם המפתח לא קיים, קריאה אל append() יוצרת את המפתח ומגדירה את הערך. מי יכול באמצעות JavaScript או כותרות תגובה.

  • באמצעות JavaScript

    כדי לעדכן ערכים של מפתחות קיימים, צריך להשתמש ב-sharedStorage.append() דרך בתוך ה-worklet או מחוצה לו.

    window.sharedStorage.append('myKey', 'myValue1');
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.append('myKey', 'myValue2');
    // Shared Storage: {'myKey': 'myValue1myValue2'}
    window.sharedStorage.append('anotherKey', 'hello');
    // Shared Storage: {'myKey': 'myValue1myValue2', 'anotherKey': 'hello'}
    

    כדי לצרף בתוך ה-worklet:

    sharedStorage.append('myKey', 'myValue1');
    
  • שימוש בכותרות תגובה

    בדומה להגדרת ערך ב-Shared Storage, אפשר להשתמש Shared-Storage-Write בכותרת התגובה שצריך להעביר בצמד המפתח/ערך.

    Shared-Storage-Write : append;key="myKey";value="myValue2"
    

קריאה מהאחסון המשותף

אפשר לקרוא מ-Shared Storage רק מתוך worklet.

await sharedStorage.get('mykey');

המקור של הקשר הגלישה שממנו נטען מודול ה-worklet קובע שנפח האחסון המשותף של מי נקרא.

מתבצעת מחיקה מהאחסון המשותף

ניתן לבצע מחיקות מאחסון משותף באמצעות JavaScript מבפנים או מחוץ ל-worklet או באמצעות כותרות תגובה עם delete(). כדי למחוק כל המקשים בו-זמנית, יש להשתמש ב-clear() מכל אחד מהמקשים.

  • באמצעות JavaScript

    כדי למחוק מ-Shared Storage מחוץ ל-worklet:

    window.sharedStorage.delete('myKey');
    

    כדי למחוק מ-Shared Storage מתוך ה-worklet:

    sharedStorage.delete('myKey');
    

    כדי למחוק את כל המפתחות בבת אחת מחוץ ל-worklet:

    window.sharedStorage.clear();
    

    כדי למחוק את כל המפתחות בבת אחת מתוך ה-worklet:

    sharedStorage.clear();
    
  • שימוש בכותרות תגובה

    כדי למחוק ערכים באמצעות כותרות תגובה, אפשר גם להשתמש בפקודה Shared-Storage-Write בכותרת התגובה כדי להעביר את המפתח למחיקה.

    delete;key="myKey"
    

    כדי למחוק את כל המפתחות באמצעות כותרות תגובה:

    clear;
    

שינוי הקשר

נתוני האחסון השיתופי נכתבים אל origin (לדוגמה, https://example.adtech.com) של הקשר הגלישה שהקריאה הגיעה מ-.

כשטוענים את הקוד של הצד השלישי באמצעות תג <script>, הקוד מופעל בהקשר של כלי ההטמעה. לכן, כשהקוד של צד שלישי קוראת ל-sharedStorage.set(), הנתונים נכתבים בתפריט המשותף של כלי ההטמעה אחסון. כשטוענים את הקוד של צד שלישי בתוך iframe, הקוד מקבל הקשר גלישה חדש, והמקור שלו הוא המקור של ה-iframe. לכן, הקריאה sharedStorage.set() שמגיעה מה-iframe מאחסנת את הנתונים אחסון משותף של מקור ה-iframe.

הקשר ביחס לאינטראקציה ישירה (First-Party)

אם בדף של צד ראשון מוטמע קוד JavaScript של צד שלישי שקורא sharedStorage.set() או sharedStorage.delete(), צמד המפתח/ערך נשמר בהקשר של הצד הראשון.

הנתונים מאוחסנים בדף של צד ראשון עם JavaScript מוטמע של צד שלישי.

הקשר לצד שלישי

אפשר לאחסן את צמד המפתח/ערך בהקשר של טכנולוגיית הפרסום או צד שלישי, למשל יצירת iframe והפעלה של set() או delete() בקוד ה-JavaScript ב-iframe.

נתונים שמאוחסנים בהקשר של פרסום דיגיטלי או של צד שלישי.

Private Aggregation API

כדי למדוד נתונים נצברים שמאוחסנים באחסון משותף, אפשר להשתמש ממשק API של צבירת נתונים.

כדי ליצור דוח, צריך להפעיל את contributeToHistogram() בתוך worklet עם קטגוריה וערך. הקטגוריה מיוצגת על ידי מספר שלם לא חתום של 128 ביט צריך להעביר לפונקציה BigInt. הערך הזה הוא מספר שלם חיובי.

כדי להגן על הפרטיות, המטען הייעודי (Payload) של הדוח, שמכיל את הקטגוריה והערך, מוצפן בזמן ההעברה, וניתן לפענח אותו ולאסוף אותו רק באמצעות שירות צבירת נתונים.

הדפדפן גם יגביל את התרומות שהאתר יכול להוסיף לפלט שאילתה. באופן ספציפי, התוכן תקציב מגביל את סך כל הדוחות מאתר אחד לדפדפן נתון את חלון הזמן הנתון בכל הקטגוריות. אם קיימת חריגה מהתקציב הנוכחי, לא יופק דוח.

privateAggregation.contributeToHistogram({
  bucket: BigInt(myBucket),
  value: parseInt(myBucketValue)
});

הפעלת אחסון משותף וצבירת נתונים פרטית

שימוש ב-iframe ממקורות שונים

יש צורך ב-iframe כדי להפעיל את ה-worklet של האחסון המשותף.

ב-iframe של המודעה, כדי לטעון את מודול ה-worklet באמצעות קריאה ל-addModule(). כדי להריץ את שרשומה בקובץ ה-worklet sharedStorageWorklet.js, JavaScript של iframe זהה של מודעה, קוראים לפונקציה sharedStorage.run().

await window.sharedStorage.worklet.addModule('modules/sharedStorageWorklet.js');
await window.sharedStorage.worklet.run('shared-storage-report', {
  data: { campaignId: '1234' },
});

בסקריפט של ה-worklet, צריך ליצור מחלקה עם run אסינכרוני . וregister את הכיתה הזו כדי להריץ ב-iframe של המודעה. פנים החנות sharedStorageWorklet.js:

class SharedStorageReportOperation {
  async run(data) {
    // Other code goes here.
    bucket = getBucket(...);
    value = getValue(...);
    privateAggregation.contributeToHistogram({
      bucket: bucket,
      value: value
    });
  }
}
register('shared-storage-report',
  SharedStorageReportOperation);

שימוש בבקשה ממקורות שונים

אחסון משותף וצבירה פרטית מאפשרים ליצור worklets ממקורות שונים ללא צורך ברכיבי iframe ממקורות שונים.

הדף של הצד הראשון יכול להפעיל קריאה ל-createWorklet() למקורות שונים נקודת הקצה ב-JavaScript.

async function crossOriginCall() {
  let privateAggregationWorklet = await sharedStorage.createWorklet(
    'https://cross-origin.dev/js/worklet.js',
  );
  await privateAggregationWorklet.run('pa-worklet');
}
crossOriginCall();

נקודת הקצה (endpoint) של JavaScript ממקורות שונים תצטרך להגיב עם הכותרות Shared-Storage-Cross-Origin-Worklet-Allowed ומאפשרים בין מקורות באמצעות Access-Control-Allow-Origin.

Shared-Storage-Cross-Origin-Worklet-Allowed : ?1
Access-Control-Allow-Origin : https://first-party.dev

ל-worklets שנוצרו באמצעות createWorklet() יהיו selectURL ו-run(). הפונקציה addModule() לא זמינה לאפשרות הזו.

class CrossOriginWorklet {
  async run(data){
    // Other code goes here.
    bucket = getBucket(...);
    value = getValue(...);
    privateAggregation.contributeToHistogram({
      bucket: bucket,
      value: value
    });
  }
}

ניפוי באגים

כדי להפעיל ניפוי באגים, צריך להפעיל את שיטת ה-JavaScript enableDebugMode() באותה הקשר שבו נעשה שימוש באחסון משותף ובצבירה פרטית. זו תהיה יחולו על דוחות עתידיים באותו הקשר.

privateAggregation.enableDebugMode();

כדי לשייך את הדוחות להקשרים שגרמו להפעלה שלהם, אפשר להגדיר מפתח ניפוי באגים של מספר שלם לא חתום של 64 ביט, שמועבר לקריאה של JavaScript. debugKey הוא BigInt.

privateAggregation.enableDebugMode({debugKey: 1234});

ניפוי באגים בנפח האחסון המשותף

Shared Storage מחזיר הודעת שגיאה גנרית:

Promise is rejected without and explicit error message

אפשר לנפות באגים ב-Shared Storage על ידי גלישת השיחות עם try-catch של משפטים יחידים,

try {
  privateAggregation.contributeToHistogram({bucket, value});
} catch (e){
  console.log(e);
}

ניפוי באגים בצבירה פרטית

הדיווחים נשלחים אל /.well-known/private-aggregation/report-shared-storage וגם /.well-known/private-aggregation/debug/report-shared-storage. דוחות של ניפוי באגים מקבלים מטען ייעודי (payload) שדומה ל-JSON הבא. המטען הייעודי (Payload) הזה מגדיר את api בתור 'Shared-storage' (אחסון משותף).

{
   "aggregation_coordinator_origin": "https://publickeyservice.msmt.gcp.privacysandboxservices.com",
   "aggregation_service_payloads": [ {
      "debug_cleartext_payload": "omRkYXRhlKJldmFsdWVEAAAAgGZidWNrZXRQAAAAAAAAAAAAAAAAB1vNFaJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAKJldmFsdWVEAAAAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAAAGlvcGVyYXRpb25paGlzdG9ncmFt",
      "key_id": "1569ab37-da44-4a26-80d9-5ed6524ab2a7",
      "payload": "/9nHrWn1MnJWRxFvanbubciWE9mPyIij6uYLi5k351eQCd3/TZpe2knaatUNcniq4a4e61tmKebv50OmMRZFnnCfcAwIdIgLHu1a3en97PojqWJBfO52RiVMIcP7KQTLzMxq2LhvPSdV4zjXo1Teu/JuIK3LIyis3vUMpS+tUAX0QV+I6X5SVmZFiNW9aMb8DwLOtqrBy5JJ/EkOIY0G+1Fi1/3R7UtKsqM1o71A/OzdmlNkwO7EV/VUNinGvWnd19FvDHe/kqkNdTHKbhAnMmbZzHW9bsEQS81leElCla6BTdbdbeeFU/jbTj0AOaoNOIe5r7FU5NG6nW4ULXTCbLLjTQ1mtl3id3IP41Zin1JvABCDC/HUSgLFz8EUqkmbMIOlMfNYA79aURq6FqE0GO0HtICYf0GPNdVv7p4jY3FNn6+JS4l5F3t+3lP9ceo4IpCE+31jzMtYJ+19xFh6C5ufteBR/iknZFcc1w3caQBhgRl5jt8DbaOzYcW4690H8Ul4Oh2wRO+6/njifk+pExLay/O5swLi2lUUph5OUEaaztwwzh2mnhwIBxMkPnfsGihiF+5KDEajVfMZ3NLsIDoZO+l4RTZrkqE+jVkAqaZGBiCIx42Edp/JV0DXfrryypCdQBZr8iEbSzCM9hKsMfLN7S/VkPe5rDwOZbhKCn5XXgfGz5tSx/KbZgsQf4OCEhwAyNPHAh3MHU7xmkQ3pKg4EIUC/WOtKAlVDOtDMmPPoQY1eAwJhw9SxZaYF1kHjUkTm3EnGhgXgOwCRWqeboNenSFaCyp6DbFNI3+ImONMi2oswrrZO+54Tyhca5mnLIiInI+C3SlP4Sv1jFECIUdf/mifJRM5hMj6OChzHf4sEifjqtD4A30c4OzGexWarie2xakdQej9Go4Lm0GZEDBfcAdWLT9HwmpeI2u4HDAblXDvLN8jYFDOOtzOl90oU7AwdhkumUCFLRadXAccXW9SvLfDswRkXMffMJLFqkRKVE1GPonFFtlzaRqp7IgE8L6AOtz6NDcxAjHnEuzDPPMcWMl1AFH0gq7h"
   } ],
   "debug_key": "1234",
   "shared_info": "{\"api\":\"shared-storage\",\"debug_mode\":\"enabled\",\"report_id\":\"80d93c0a-a94e-4ab7-aeb5-a4ecd4bfc598\",\"reporting_origin\":\"https://privacy-sandbox-demos-dsp.dev\",\"scheduled_report_time\":\"1717784740\",\"version\":\"0.1\"}"
}

ניפוי באגים במטען ייעודי (payload) של טקסט ללא באגים

debug_cleartext_payload הוא Base64 קידוד CBOR. אפשר לצפות בקטגוריה באמצעות המפענח או באמצעות הפקודה קוד ה-JavaScript שנמצא בתיקיית האחסון המשותף וממפענח.

השלבים הבאים

הדפים הבאים מסבירים היבטים חשובים של 'אחסון משותף' ושל 'פרטי' ממשקי API של צבירה.

אחרי שתכירו את ממשקי ה-API, תוכלו להתחיל לאסוף את הדוחות, שנשלחות כבקשת POST לנקודות הקצה הבאות כ-JSON גוף הבקשה.

  • דוחות ניפוי באגים – context-origin/.well-known/private-aggregation/debug/report-shared-storage
  • דוחות – context-origin/.well-known/private-aggregation/report-shared-storage

אחרי איסוף הדוחות, אפשר לבצע בדיקות באמצעות הבדיקה המקומית כלי או להגדיר את סביבת הביצוע המהימנה לצבירת נתונים שירות כדי לקבל את הדוחות המצטברים.

משתפים משוב

תוכלו לשתף משוב על ממשקי ה-API והמסמכים ב-GitHub.