Depolama Erişim API'sı

Tarayıcılar, kullanıcı ayarları ve depolama alanı bölme tarafından üçüncü taraf çerezlerinin engellenmesi, kimlik doğrulama gibi kullanıcı yolculukları için yerleşik bağlamlarda çerezlere ve diğer depolama alanlarına dayanan siteler ve hizmetler açısından zorluk oluşturur. Storage Access API (SAA), siteler arası izlemeyi mümkün olduğunca sınırlarken bu kullanım alanlarının çalışmaya devam etmesine olanak tanır.

Uygulama durumu

Tarayıcı desteği

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

Kaynak

Storage Access API, tüm büyük tarayıcılarda kullanılabilir ancak tarayıcılar arasında ufak uygulama farklılıkları vardır. Bu farklar, bu yayındaki ilgili bölümlerde vurgulanmıştır.

API'yi standartlaştırmadan önce kalan tüm engelleme sorunlarını çözmek için çalışmalarımız devam ediyor.

Storage Access API nedir?

Storage Access API, tarayıcı ayarları tarafından reddedileceği durumlarda iframe'lerin depolama alanı erişim izinleri istemesine olanak tanıyan bir JavaScript API'sidir. Siteler arası kaynakların yüklenmesine bağlı kullanım alanlarına sahip yerleşimler, gerektiğinde kullanıcıdan erişim izni istemek için API'yi kullanabilir.

Depolama alanı isteği kabul edilirse iframe, bölümlenmemiş çerezlerine ve depolama alanına erişebilir. Bu çerezler ve depolama alanı, kullanıcılar iframe'ı üst düzey bir site olarak ziyaret ettiğinde de kullanılabilir.

Storage Access API, genellikle kullanıcı takibi için kullanılan genel bölümlenmemiş çerez ve depolama alanı erişimini engellerken son kullanıcıya minimum düzeyde yük bindirerek belirli bölümlenmemiş çerez ve depolama alanı erişiminin sağlanmasına olanak tanır.

Kullanım alanları

Bazı üçüncü taraf yerleşik içerikleri, kullanıcıya daha iyi bir deneyim sunmak için bölümlenmemiş çerezlere veya depolamaya erişim gerektirir. Üçüncü taraf çerezleri kısıtlandığında ve depolama alanı bölümlendirmesi etkinleştirildiğinde bu erişim mümkün olmaz.

Kullanım alanları şunlardır:

  • Giriş oturumu ayrıntılarını gerektiren yerleştirilmiş yorum widget'ları.
  • Giriş oturumu ayrıntılarını gerektiren sosyal medya "Beğen" düğmeleri.
  • Giriş oturumu ayrıntılarını gerektiren yerleştirilmiş belgeler.
  • Video yerleşimine sunulan premium deneyim (ör. oturum açmış kullanıcılara reklam göstermemek, kullanıcının altyazı tercihlerini öğrenmek veya belirli video türlerini kısıtlamak için).
  • Yerleşik ödeme sistemleri.

Bu kullanım alanlarının çoğu, yerleşik iFrame'lerde kalıcı oturum açma erişimini içerir.

Diğer API'ler yerine Storage Access API'yi ne zaman kullanmalısınız?

Storage Access API, bölümlenmemiş çerez ve depolama alanını kullanmanın alternatiflerinden biridir. Bu nedenle, bu API'nin diğer API'lere kıyasla ne zaman kullanılacağını anlamak önemlidir. Aşağıdakilerin her ikisinin de geçerli olduğu kullanım alanları için tasarlanmıştır:

  • Kullanıcı, yerleştirilmiş içerikle etkileşim kurar. Yani bu, pasif veya gizli bir iFrame değildir.
  • Kullanıcı, yerleştirilmiş kaynağı üst düzey bir bağlamda ziyaret ettiyse (yani bu kaynak başka bir siteye yerleştirilmemişse).

Çeşitli kullanım alanları için alternatif API'ler vardır:

  • Bağımsız Bölümlendirme Durumuna Sahip Çerezler (CHIPS), geliştiricilerin üst düzey site başına ayrı bir çerez kabı ile "bölünmüş" depolama alanına çerez etkinleştirmesine olanak tanır. Örneğin, üçüncü taraf bir web sohbet widget'ı, oturum bilgilerini kaydetmek için çerez ayarlayabilir. Oturum bilgileri site başına kaydedilir. Bu nedenle, widget tarafından ayarlanan çereze, yerleştirildiği diğer web sitelerinde de erişilmesi gerekmez. Depolama Aksesuarı API'si, yerleşik bir üçüncü taraf widget'ı aynı bilgileri farklı kaynaklarda paylaşmaya bağlı olduğunda (ör. oturum açmış kullanıcıların oturum ayrıntıları veya tercihleri için) yararlıdır.
  • Depolama alanı bölümlendirmesi, siteler arası iFrame'lerin mevcut JavaScript depolama mekanizmalarını kullanırken temel depolama alanını site başına bölmesidir. Bu sayede, bir web sitesindeki yerleşik depolama alanına diğer web sitelerindeki aynı yerleşik öğe tarafından erişilemez.
  • İlgili Web Siteleri Grupları (RWS), kuruluşların siteler arasındaki ilişkileri tanımlamasını sağlar. Böylece tarayıcılar, belirli amaçlar için sınırlı, bölümlenmemiş çerez ve depolama erişimine izin verebilir. Sitelerin, Storage Access API ile erişim isteğinde bulunmasına devam etmesi gerekir ancak gruptaki siteler için erişim, kullanıcı istemi olmadan verilebilir.
  • Federated Credential Management (FedCM), birleşik kimlik hizmetlerinde gizliliği korumaya yönelik bir yaklaşımdır. Storage Access API, bölümlenmemiş çerezlere ve giriş sonrası depolama alanına erişimle ilgilenir. FedCM, bazı kullanım alanları için Storage Access API'ye alternatif bir çözüm sunar ve daha giriş odaklı bir tarayıcı istemi içerdiğinden tercih edilebilir. Ancak FedCM'yi kullanmaya başlamak genellikle kodunuzda ek değişiklikler yapılmasını gerektirir (ör. HTTP uç noktalarını desteklemek için).
  • Sahtekarlıkla mücadele, reklamla ilgili ve ölçüm API'leri de vardır. Depolama Aksesuarı API'si bu endişeleri gidermek için tasarlanmamıştır.

Storage Access API'yi kullanma

Storage Access API'de, söze dayalı iki yöntem vardır:

Ayrıca Permissions API ile de entegre olur. Bu sayede, depolama alanı erişim izninin üçüncü taraf bağlamındaki durumunu kontrol edebilirsiniz. Bu durum, document.requestStorageAccess() çağrısının otomatik olarak verilip verilmeyeceğini belirtir:

hasStorageAccess() yöntemini kullanın

Bir site ilk kez yüklendiğinde, üçüncü taraf çerezlerine erişimin önceden verilmiş olup olmadığını kontrol etmek için hasStorageAccess() yöntemini kullanabilir.

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

Depolama erişimi, yalnızca requestStorageAccess(), çağrıldıktan sonra bir iframe belgesine verilir. Bu nedenle, aynı iframe'deki aynı kaynaktaki başka bir belgeye erişim izni verilmiş olduğu durumlar hariç olmak üzere hasStorageAccess() başlangıçta her zaman yanlış değerini döndürür. İzin, özellikle HTML belgesinin ilk isteğinde çerezlerin bulunmasını gerektiren sayfalara erişim izni verildikten sonra yeniden yükleme yapılmasına izin vermek için iFrame içindeki aynı kaynak gezinmelerinde korunur.

requestStorageAccess() hareketini kullanın

iFrame'in erişimi yoksa requestStorageAccess() yöntemini kullanarak erişim isteğinde bulunması gerekebilir:

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

Bu istek ilk kez yapıldığında kullanıcının bir tarayıcı istemi ile bu erişimi onaylamasının gerekmesi mümkündür. Bu işlemden sonra söz çözülür veya await kullanılıyorsa istek reddedilerek bir istisna oluşur.

Kötüye kullanımı önlemek amacıyla bu tarayıcı istemi yalnızca kullanıcı etkileşiminden sonra gösterilir. Bu nedenle, requestStorageAccess() işlevinin başlangıçta iframe yüklendikten hemen sonra değil, kullanıcı tarafından etkinleştirilen bir etkinlik işleyicisinden çağrılması gerekir:

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

Çerezler yerine yerel depolama alanı kullanmanız gerekiyorsa aşağıdakileri yapabilirsiniz:

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

İzin istemleri

Kullanıcı düğmeyi ilk kez tıkladığında tarayıcı istemi çoğu durumda otomatik olarak (genellikle adres çubuğunda) görünür. Aşağıdaki ekran görüntüsünde Chrome'un istemi gösterilmektedir. Diğer tarayıcıların kullanıcı arayüzü de benzerdir:

Chrome Storage Access API izin istemi
Chrome'un Storage Access API izin istemi

İstem, tarayıcı tarafından atlanabilir ve belirli durumlarda izin otomatik olarak verilebilir:

  • Sayfa ve iFrame, istemi kabul ettikten sonraki son 30 gün içinde kullanıldıysa.
  • Yerleştirilmiş iFrame, ilgili web sitesi grubunun bir parçasıysa.
  • Depolama alanı erişimi için FedCM güven sinyali olarak kullanılıyorsa.
  • Firefox'ta, bilinen web siteleri (en üst düzeyde etkileşimde bulunduğunuz siteler) için de ilk beş denemede istem atlanır.

Alternatif olarak, belirli durumlarda istem gösterilmeden yöntem otomatik olarak reddedilebilir:

  • Kullanıcı, daha önce iFrame'de değil, üst düzey bir doküman olarak iFrame'in sahibi olan siteyi ziyaret edip siteyle etkileşimde bulunmadıysa. Bu, Depolama Alanı Erişimi API'sinin yalnızca kullanıcıların daha önce birinci taraf bağlamında ziyaret ettiği yerleşik siteler için yararlı olduğu anlamına gelir.
  • requestStorageAccess() yöntemi, bir etkileşimden sonra istem için önceden onay alınmadan kullanıcı etkileşimi etkinliğinin dışında çağrılırsa.

İlk kullanımda kullanıcıdan izin istenmesine rağmen sonraki ziyaretlerde requestStorageAccess(), Chrome ve Firefox'ta istem gösterilmeden ve kullanıcı etkileşimi gerekmeden çözülebilir. Safari'de her zaman kullanıcı etkileşiminin gerekli olduğunu unutmayın.

Çerez ve depolama erişimi istem veya kullanıcı etkileşimi olmadan verilebileceğinden, sayfa yüklenirken requestStorageAccess() çağrılarak bunu destekleyen tarayıcılarda (Chrome ve Firefox) kullanıcı etkileşiminden önce genellikle bölümlenmemiş çerez veya depolama erişimi elde edilebilir. Bu sayede, bölümlenmemiş çerezlere ve depolamaya hemen erişebilir ve kullanıcı iframe ile etkileşime geçmeden önce bile daha kapsamlı bir deneyim sunabilirsiniz. Bu, bazı durumlarda kullanıcı etkileşimini beklemekten daha iyi bir kullanıcı deneyimi sunabilir.

SAA için güven sinyali olarak FedCM

FedCM (Federated Credential Management - Birleştirilmiş Kimlik Bilgisi Yönetimi), birleşik kimlik hizmetlerinde (ör. "... ile oturum aç") üçüncü taraf çerezlerine veya gezinme yönlendirmelerine dayanmayan, gizliliği korumaya yönelik bir yaklaşımdır.

Bir kullanıcı, FedCM ile üçüncü taraf kimlik sağlayıcıdan (IdP) bazı yerleşik içeriğe sahip bir Güvenen Taraf'a (RP) giriş yaptığında, yerleşik IdP içeriği kendi üst düzey bölümlenmemiş çerezlerine otomatik olarak depolama erişimi elde edebilir. FedCM ile otomatik depolama alanı erişimini etkinleştirmek için aşağıdaki koşulların karşılanması gerekir:

  • FedCM kimlik doğrulaması (kullanıcı oturum açma durumu) etkin olmalıdır.
  • RP, identity-credentials-get iznini ayarlayarak etkinleştirmiştir. Örneğin:
<iframe src="https://idp.example" allow="identity-credentials-get"></iframe>

Örneğin, idp.example iframe'i rp.example içine yerleştirilmiştir. Kullanıcı FedCM ile giriş yaptığında idp.example iFrame'i kendi üst düzey çerezleri için depolama erişimi isteyebilir.

rp.example, kullanıcıyı kimlik sağlayıcı idp.example ile oturum açmak için FedCM çağrısı yapar:

// 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',
    }],
  },
});

Kullanıcı giriş yaptıktan sonra, RP'nin İzin Politikası ile buna açıkça izin vermesi koşuluyla IdP, idp.example iFrame'inden requestStorageAccess()'ü çağırabilir. Yerleştirilen içeriğe, kullanıcının etkinleştirmesi veya başka bir izin istemi gerekmeden kendi üst düzey çerezine otomatik olarak depolama erişimi verilir:

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

İzin yalnızca kullanıcı FedCM ile oturum açtığında otomatik olarak verilir. Kimlik doğrulama devre dışı olduğunda depolama alanı erişimi vermek için standart SAA koşulları geçerli olur.

storage-access izin sorgusunu kullanma

Erişimin kullanıcı etkileşimi olmadan verilip verilemeyeceğini kontrol etmek için storage-access izninin durumunu kontrol edebilir ve etkileşim gerektiğinde çağrıyı yapıp başarısız olmasını sağlamak yerine, yalnızca kullanıcı işlemi gerekmiyorsa requestStoreAccess() çağrısını erkenden yapabilirsiniz.

Bu sayede, farklı içerikler (ör. giriş düğmesi) göstererek istem ihtiyacını önceden karşılayabilirsiniz.

Aşağıdaki kod, önceki örneğe storage-access izin kontrolünü ekler:

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

Korumalı alana alınan iframe'ler

Storage Access API'si kısıtlı alan içeren iframe'lerde kullanılırken aşağıdaki korumalı alan izinleri gereklidir:

  • Storage Access API'ye erişime izin vermek için allow-storage-access-by-user-activation gereklidir.
  • API'yi çağırmak için JavaScript kullanımına izin vermek üzere allow-scripts gereklidir.
  • Aynı kaynaktan çerezlere ve diğer depolama alanlarına erişime izin vermek için allow-same-origin gereklidir.

Örneğin:

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

Chrome'da Storage Access API ile erişilebilmesi için siteler arası çerezlerin aşağıdaki iki özellikle ayarlanması gerekir:

  • SameSite=None: Çerezin siteler arası olarak işaretlenmesi için gereklidir.
  • Secure: Yalnızca HTTPS siteleri tarafından ayarlanan çerezlere erişilebilmesini sağlar.

Firefox ve Safari'de çerezler varsayılan olarak SameSite=None olarak ayarlanır ve SAA'yı Secure çerezleriyle kısıtlamazlar. Bu nedenle bu özellikler gerekli değildir. SameSite özelliğiyle ilgili olarak açık bir şekilde bilgi vermeniz ve her zaman Secure çerezleri kullanmanız önerilir.

Üst düzey sayfa erişimi

Storage Access API, yerleştirilmiş iFrame'lerde üçüncü taraf çerezlerine erişimi etkinleştirmeyi amaçlar.

Üst düzey sayfanın üçüncü taraf çerezlerine erişmesi gereken başka kullanım alanları da vardır. Örneğin, site sahiplerinin bir iframe yerine doğrudan üst düzey dokümana dahil etmek isteyebileceği, çerezlerle kısıtlanmış resimler veya komut dosyaları. Chrome, bu kullanım alanını ele almak için requestStorageAccessFor() yöntemi ekleyen Storage Access API'nin bir uzantısını önermiştir.

requestStorageAccessFor() yöntemi

Tarayıcı desteği

  • Chrome: 119.
  • Edge: 119.
  • Firefox: Desteklenmez.
  • Safari: Desteklenmez.

Kaynak

requestStorageAccessFor() yöntemi, requestStorageAccess() ile benzer şekilde çalışır ancak üst düzey kaynaklar için kullanılır. Yalnızca üçüncü taraf çerezlerine genel erişim verilmesini önlemek için İlgili Web Sitesi Grubu'ndaki siteler için kullanılabilir.

requestStorageAccessFor()'ü kullanma hakkında daha fazla bilgi için İlişkili Websitesi Grupları: Geliştirici Kılavuzu'nu okuyun.

top-level-storage-access izin sorgusu

Tarayıcı desteği

  • Chrome: Desteklenmez.
  • Edge: Desteklenmez.
  • Firefox: Desteklenmez.
  • Safari: Desteklenmez.

storage-access iznine benzer şekilde, requestStorageAccessFor() için erişim verilip verilemeyeceğini kontrol etmek üzere top-level-storage-access izni vardır.

RWS ile birlikte kullanıldığında Storage Access API'nin farkı nedir?

İlgili Web Sitesi Kümeleri, Depolama Alanı Erişimi API'si ile birlikte kullanıldığında aşağıdaki tabloda ayrıntılı olarak açıklanan belirli ek özellikler kullanılabilir:

RWS olmadan RWS ile
Depolama alanı erişim isteğini başlatmak için kullanıcı hareketi gerekir.
Erişim izni vermeden önce kullanıcının istenen depolama alanı kaynağını üst düzey bir bağlamda ziyaret etmesini gerektirir
İlk kez kullanıcı istemi atlanabilir
Erişim daha önce verilmişse requestStorageAccess çağrılması gerekmez
İlgili web sitesi sitelerindeki diğer alanlara otomatik olarak erişim izni verir.
Üst düzey sayfa erişimi için requestStorageAccessFor desteklenir
Storage Access API'yi İlgili Web Sitesi Kümeleri olmadan ve İlgili Web Sitesi Kümeleri ile kullanma arasındaki farklar

Demo: Çerezleri ayarlama ve bunlara erişme

Aşağıdaki demoda, demonun ilk ekranında kendiniz belirlediğiniz bir çereze demonun ikinci sitesindeki yerleşik bir çerçeveden nasıl erişilebileceği gösterilmektedir:

storage-access-api-demo.glitch.me

Demo için üçüncü taraf çerezlerinin devre dışı bırakıldığı bir tarayıcı gerekir:

  • chrome://flags/#test-third-party-cookie-phaseout işareti ayarlanmış ve tarayıcı yeniden başlatılmış Chrome 118 veya sonraki sürümler.
  • Firefox
  • Safari

Demo: Yerel depolama alanını ayarlama

Aşağıdaki demoda, Storage Access API'yi kullanarak üçüncü taraf bir iFrame'den bölümlenmemiş yayın kanallarına nasıl erişileceği gösterilmektedir:

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

Demo için test-third-party-cookie-phaseout işaretinin etkin olduğu Chrome 125 veya daha yeni bir sürüm gerekir.

Kaynaklar