API Akses Penyimpanan

Pemblokiran cookie pihak ketiga oleh browser, setelan pengguna, dan partisi penyimpanan, menimbulkan tantangan bagi situs dan layanan yang mengandalkan cookie dan penyimpanan lainnya dalam konteks tersemat, untuk perjalanan pengguna seperti autentikasi. Storage Access API (SAA) memungkinkan kasus penggunaan ini terus berfungsi, sekaligus membatasi pelacakan lintas situs sebanyak mungkin.

Status penerapan

Dukungan Browser

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

Sumber

Storage Access API tersedia di semua browser utama, tetapi ada perbedaan implementasi kecil di antara browser. Perbedaan ini telah ditandai di bagian yang relevan dalam postingan ini.

Kami terus berupaya menyelesaikan semua masalah pemblokiran yang tersisa, sebelum menstandarkan API.

Apa itu Storage Access API?

Storage Access API adalah API JavaScript yang memungkinkan iframe meminta izin akses penyimpanan jika akses akan ditolak oleh setelan browser. Penyematan dengan kasus penggunaan yang bergantung pada pemuatan resource lintas situs dapat menggunakan API untuk meminta izin akses dari pengguna, sesuai kebutuhan.

Jika permintaan penyimpanan disetujui, iframe akan memiliki akses ke cookie dan penyimpanan yang tidak dipartisi, yang juga tersedia saat pengguna mengunjunginya sebagai situs tingkat atas.

Storage Access API memungkinkan akses penyimpanan dan cookie tanpa partisi tertentu diberikan dengan beban minimal kepada pengguna akhir, sekaligus tetap mencegah akses penyimpanan dan cookie tanpa partisi generik seperti yang sering digunakan untuk pelacakan pengguna.

Kasus penggunaan

Beberapa penyematan pihak ketiga memerlukan akses ke cookie atau penyimpanan yang tidak dipartisi untuk memberikan pengalaman yang lebih baik kepada pengguna—sesuatu yang tidak akan tersedia jika cookie pihak ketiga dibatasi dan partisi penyimpanan diaktifkan.

Kasus penggunaan mencakup:

  • Widget komentar tersemat yang memerlukan detail sesi login.
  • Tombol "Suka" media sosial yang memerlukan detail sesi login.
  • Dokumen tersemat yang memerlukan detail sesi login.
  • Pengalaman premium yang diberikan ke penyematan video (misalnya, untuk tidak menampilkan iklan bagi pengguna yang login, atau untuk mengetahui preferensi pengguna terkait teks tertutup atau membatasi jenis video tertentu).
  • Sistem pembayaran tersemat.

Banyak kasus penggunaan ini melibatkan akses login yang persisten di iframe tersemat.

Kapan harus menggunakan Storage Access API daripada API lainnya

Storage Access API adalah salah satu alternatif untuk menggunakan cookie dan penyimpanan yang tidak dipartisi, jadi penting untuk memahami kapan harus menggunakan API ini dibandingkan dengan yang lain. Fungsi ini ditujukan untuk kasus penggunaan dengan kedua hal berikut:

  • Pengguna akan berinteraksi dengan konten tersemat—yaitu, bukan iframe pasif atau iframe tersembunyi.
  • Pengguna telah mengunjungi origin tersemat dalam konteks tingkat atas—yaitu, saat origin tersebut tidak disematkan di situs lain.

Ada API alternatif untuk berbagai kasus penggunaan:

  • Cookie yang Memiliki Status Partisi Independen (CHIPS) memungkinkan developer memilih untuk mengaktifkan cookie ke penyimpanan "terpartisi", dengan cookie jar terpisah per situs tingkat teratas. Misalnya, widget web chat pihak ketiga dapat mengandalkan setelan cookie untuk menyimpan informasi sesi. Informasi sesi disimpan per situs, sehingga cookie yang ditetapkan oleh widget tidak perlu diakses di situs lain tempat cookie tersebut juga disematkan. Storage Access API berguna saat widget pihak ketiga tersemat bergantung pada berbagi informasi yang sama di berbagai asal (misalnya untuk detail atau preferensi sesi login).
  • Partisi Penyimpanan adalah cara bagi iframe lintas situs untuk menggunakan mekanisme penyimpanan JavaScript yang ada sekaligus membagi penyimpanan pokok per situs. Hal ini mencegah penyimpanan tersemat di satu situs diakses oleh penyematan yang sama di situs lain.
  • Set Situs Terkait (RWS) adalah cara bagi organisasi untuk mendeklarasikan hubungan antarsitus, sehingga browser mengizinkan akses penyimpanan dan cookie yang tidak dipartisi terbatas untuk tujuan tertentu. Situs masih perlu meminta akses dengan Storage Access API, tetapi untuk situs dalam kumpulan, akses dapat diberikan tanpa perintah pengguna.
  • Federated Credential Management (FedCM) adalah pendekatan yang menjaga privasi untuk layanan identitas gabungan. Storage Access API menangani akses ke cookie dan penyimpanan tanpa partisi setelah login. Untuk beberapa kasus penggunaan, FedCM menyediakan solusi alternatif untuk Storage Access API, dan mungkin lebih disukai karena menampilkan perintah browser yang lebih berorientasi pada login. Namun, mengadopsi FedCM biasanya memerlukan perubahan tambahan pada kode Anda, misalnya untuk mendukung endpoint HTTP-nya.
  • API anti-penipuan, terkait iklan, dan pengukuran juga ada, dan Storage Access API tidak dimaksudkan untuk mengatasi masalah tersebut.

Menggunakan Storage Access API

Storage Access API memiliki dua metode berbasis promise:

API ini juga terintegrasi dengan Permissions API. Hal ini memungkinkan Anda memeriksa status izin akses penyimpanan dalam konteks pihak ketiga, yang menunjukkan apakah panggilan ke document.requestStorageAccess() akan otomatis diberikan:

Menggunakan metode hasStorageAccess()

Saat pertama kali dimuat, situs dapat menggunakan metode hasStorageAccess() untuk memeriksa apakah akses ke cookie pihak ketiga telah diberikan.

// 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();

Akses penyimpanan hanya diberikan ke dokumen iframe setelah memanggil requestStorageAccess(), sehingga hasStorageAccess() akan selalu menampilkan nilai salah pada awalnya—kecuali jika dokumen dengan origin yang sama di iframe yang sama telah diberi akses. Pemberian dipertahankan di seluruh navigasi dengan origin yang sama di dalam iframe, khususnya untuk mengizinkan pemuatan ulang setelah memberikan akses untuk halaman yang mewajibkan cookie ada dalam permintaan awal untuk dokumen HTML.

Gunakan requestStorageAccess()

Jika tidak memiliki akses, iframe mungkin perlu meminta akses menggunakan metode requestStorageAccess():

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

Saat pertama kali diminta, pengguna mungkin perlu menyetujui akses ini dengan perintah browser, setelah itu promise akan di-resolve, atau akan ditolak sehingga menghasilkan pengecualian jika await digunakan.

Untuk mencegah penyalahgunaan, perintah browser ini hanya akan ditampilkan setelah interaksi pengguna. Itulah sebabnya requestStorageAccess() awalnya perlu dipanggil dari pengendali peristiwa yang diaktifkan pengguna, bukan langsung saat iframe dimuat:

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);

Jika perlu menggunakan penyimpanan lokal, bukan cookie, Anda dapat melakukan hal berikut:

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);

Permintaan izin

Saat pengguna mengklik tombol untuk pertama kalinya, perintah browser akan muncul secara otomatis dalam sebagian besar kasus, biasanya di kolom URL. Screenshot berikut menunjukkan contoh perintah Chrome, tetapi browser lain memiliki UI yang serupa:

Permintaan izin Chrome Storage Access API
Perintah izin Storage Access API Chrome

Permintaan dapat dilewati oleh browser dan izin diberikan secara otomatis dalam situasi tertentu:

  • Jika halaman dan iframe telah digunakan dalam 30 hari terakhir setelah menerima perintah.
  • Jika iframe tersemat adalah bagian dari Set Situs Terkait.
  • Jika FedCM digunakan sebagai sinyal kepercayaan untuk akses penyimpanan.
  • Di Firefox, perintah ini juga dilewati untuk situs yang diketahui (situs yang telah Anda gunakan di tingkat teratas) selama lima percobaan pertama.

Atau, metode dapat ditolak secara otomatis tanpa menampilkan perintah dalam situasi tertentu:

  • Jika pengguna belum pernah mengunjungi dan berinteraksi dengan situs yang memiliki iframe sebagai dokumen tingkat atas, bukan dalam iframe. Artinya, Storage Access API hanya berguna untuk situs tersemat yang sebelumnya telah dikunjungi pengguna dalam konteks pihak pertama.
  • Jika metode requestStorageAccess() dipanggil di luar peristiwa interaksi pengguna tanpa persetujuan sebelumnya dari perintah setelah interaksi.

Meskipun pengguna akan diminta untuk melakukan penggunaan awal, kunjungan berikutnya dapat me-resolve requestStorageAccess() tanpa permintaan dan tanpa memerlukan interaksi pengguna di Chrome dan Firefox. Perhatikan bahwa Safari selalu memerlukan interaksi pengguna.

Karena akses cookie dan penyimpanan dapat diberikan tanpa perintah, atau interaksi pengguna, sering kali Anda bisa mendapatkan akses cookie atau penyimpanan yang tidak dipartisi sebelum interaksi pengguna di browser yang mendukungnya (Chrome dan Firefox) dengan memanggil requestStorageAccess() saat halaman dimuat. Hal ini dapat memungkinkan Anda mengakses cookie dan penyimpanan yang tidak dipartisi dengan segera serta memberikan pengalaman yang lebih lengkap, bahkan sebelum pengguna berinteraksi dengan iframe. Hal ini dapat menjadi pengalaman pengguna yang lebih baik untuk beberapa situasi daripada menunggu interaksi pengguna.

FedCM sebagai sinyal kepercayaan untuk SAA

FedCM (Federated Credential Management) adalah pendekatan yang menjaga privasi untuk layanan identitas gabungan (seperti "Login dengan...") yang tidak mengandalkan cookie pihak ketiga atau pengalihan navigasi.

Saat pengguna login ke Pihak Penerima (RP) yang memiliki beberapa konten tersemat dari penyedia identitas (IdP) pihak ketiga dengan FedCM, konten IdP tersemat dapat otomatis mendapatkan akses penyimpanan ke cookie tingkat teratas yang tidak dipartisi. Untuk mengaktifkan akses penyimpanan otomatis dengan FedCM, kondisi berikut harus terpenuhi:

  • Autentikasi FedCM (status login pengguna) harus aktif.
  • RP telah memilih ikut serta dengan menetapkan izin identity-credentials-get, misalnya:
<iframe src="https://idp.example" allow="identity-credentials-get"></iframe>

Misalnya, iframe idp.example disematkan di rp.example. Saat pengguna login dengan FedCM, iframe idp.example dapat meminta akses penyimpanan untuk cookie tingkat teratas-nya sendiri.

rp.example membuat panggilan FedCM untuk membuat pengguna login dengan penyedia identitas 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',
    }],
  },
});

Setelah pengguna login, IdP dapat memanggil requestStorageAccess() dari dalam iframe idp.example, selama RP telah mengizinkannya secara eksplisit dengan Kebijakan Izin. Penyematan akan otomatis diberi akses penyimpanan ke cookie tingkat atas sendiri, tanpa aktivasi pengguna atau memerlukan permintaan izin lain:

// 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();

Izin akan otomatis diberikan hanya selama pengguna login dengan FedCM. Setelah autentikasi tidak aktif, persyaratan SAA standar berlaku untuk memberikan akses penyimpanan.

Menggunakan kueri izin storage-access

Untuk memeriksa apakah akses dapat diberikan tanpa interaksi pengguna, Anda dapat memeriksa status izin storage-access dan hanya melakukan panggilan requestStoreAccess() lebih awal jika tidak ada tindakan pengguna yang diperlukan, bukan memanggilnya dan membuatnya gagal saat interaksi diperlukan.

Hal ini juga memungkinkan Anda menangani kebutuhan perintah di awal dengan menampilkan konten yang berbeda—misalnya, tombol login.

Kode berikut menambahkan pemeriksaan izin storage-access ke contoh sebelumnya:

// 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 dengan sandbox

Saat menggunakan Storage Access API di iframe dengan sandbox, izin sandbox berikut diperlukan:

  • allow-storage-access-by-user-activation diperlukan untuk mengizinkan akses ke Storage Access API.
  • allow-scripts diperlukan untuk mengizinkan penggunaan JavaScript guna memanggil API.
  • allow-same-origin diperlukan untuk mengizinkan akses ke cookie dengan origin yang sama dan penyimpanan lainnya.

Contoh:

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

Agar dapat diakses dengan Storage Access API di Chrome, cookie lintas situs harus ditetapkan dengan dua atribut berikut:

  • SameSite=None - yang diperlukan untuk menandai cookie sebagai lintas situs
  • Secure - yang memastikan hanya cookie yang ditetapkan oleh situs HTTPS yang dapat diakses.

Di Firefox dan Safari, cookie ditetapkan secara default ke SameSite=None dan tidak membatasi SAA ke cookie Secure sehingga atribut ini tidak diperlukan. Sebaiknya tampilkan atribut SameSite secara eksplisit dan selalu gunakan cookie Secure.

Akses halaman tingkat atas

Storage Access API dimaksudkan untuk mengaktifkan akses ke cookie pihak ketiga dalam iframe tersemat.

Ada juga kasus penggunaan lain saat halaman tingkat teratas memerlukan akses ke cookie pihak ketiga. Misalnya, gambar atau skrip yang dibatasi oleh cookie, yang mungkin ingin disertakan langsung oleh pemilik situs dalam dokumen tingkat atas, bukan dalam iframe. Untuk mengatasi kasus penggunaan ini, Chrome telah mengusulkan ekstensi ke Storage Access API yang menambahkan metoderequestStorageAccessFor().

Metode requestStorageAccessFor()

Dukungan Browser

  • Chrome: 119.
  • Edge: 119.
  • Firefox: tidak didukung.
  • Safari: tidak didukung.

Sumber

Metode requestStorageAccessFor() berfungsi dengan cara yang mirip dengan requestStorageAccess(), tetapi untuk resource tingkat atas. Setelan ini hanya dapat digunakan untuk situs dalam Set Situs Terkait untuk mencegah pemberian akses umum ke cookie pihak ketiga.

Untuk mengetahui detail selengkapnya tentang cara menggunakan requestStorageAccessFor(), baca Set Situs Terkait: panduan developer.

Kueri izin top-level-storage-access

Dukungan Browser

  • Chrome: tidak didukung.
  • Edge: tidak didukung.
  • Firefox: tidak didukung.
  • Safari: tidak didukung.

Serupa dengan izin storage-access, ada izin top-level-storage-access untuk memeriksa apakah akses dapat diberikan untuk requestStorageAccessFor().

Apa perbedaan Storage Access API saat digunakan dengan RWS?

Saat Set Situs Terkait digunakan dengan Storage Access API, kemampuan tambahan tertentu akan tersedia seperti yang dijelaskan dalam tabel berikut:

Tanpa RWS Dengan RWS
Memerlukan gestur pengguna untuk memulai permintaan akses penyimpanan
Mewajibkan pengguna untuk mengunjungi origin penyimpanan yang diminta dalam konteks tingkat teratas sebelum memberikan akses
Perintah pengguna pertama kali dapat dilewati
requestStorageAccess tidak perlu dipanggil jika akses telah diberikan sebelumnya
Otomatis memberikan akses di seluruh domain lain di Situs Terkait
Mendukung requestStorageAccessFor untuk akses halaman tingkat teratas
Perbedaan antara penggunaan Storage Access API tanpa dan dengan Set Situs Terkait

Demo: menetapkan dan mengakses cookie

Demo berikut menunjukkan cara cookie yang Anda tetapkan di layar pertama demo dapat diakses dalam frame tersemat di situs kedua demo:

storage-access-api-demo.glitch.me

Demo ini memerlukan browser dengan cookie pihak ketiga dinonaktifkan:

  • Chrome 118 atau yang lebih baru dengan flag chrome://flags/#test-third-party-cookie-phaseout ditetapkan dan browser dimulai ulang.
  • Firefox
  • Safari

Demo: menyetel Penyimpanan Lokal

Demo berikut menunjukkan cara mengakses Saluran Siaran yang tidak dipartisi dari iframe pihak ketiga menggunakan Storage Access API:

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

Demo ini memerlukan Chrome 125 atau yang lebih baru dengan tanda test-third-party-cookie-phaseout diaktifkan.

Resource