Storage Access API (API Truy cập bộ nhớ)

Việc trình duyệt, chế độ cài đặt của người dùng và phân vùng bộ nhớ chặn cookie của bên thứ ba gây ra thách thức cho các trang web và dịch vụ dựa vào cookie và bộ nhớ khác trong ngữ cảnh nhúng, cho hành trình của người dùng như xác thực. API Truy cập bộ nhớ (SAA) cho phép các trường hợp sử dụng này tiếp tục hoạt động, đồng thời hạn chế việc theo dõi trên nhiều trang web nhiều nhất có thể.

Trạng thái triển khai

Hỗ trợ trình duyệt

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

Nguồn

Storage Access API có sẵn trong tất cả trình duyệt chính, nhưng có một số khác biệt nhỏ về cách triển khai giữa các trình duyệt. Những điểm khác biệt này đã được nêu bật trong các phần liên quan của bài đăng này.

Chúng tôi đang tiếp tục giải quyết tất cả các vấn đề chặn còn lại trước khi chuẩn hoá API.

Storage Access API là gì?

API Truy cập bộ nhớ là một API JavaScript cho phép iframe yêu cầu quyền truy cập bộ nhớ khi quyền truy cập bị từ chối theo chế độ cài đặt trình duyệt. Các trường hợp sử dụng nhúng phụ thuộc vào việc tải tài nguyên trên nhiều trang web có thể sử dụng API để yêu cầu người dùng cấp quyền truy cập (nếu cần).

Nếu yêu cầu bộ nhớ được cấp, thì iframe sẽ có quyền truy cập vào cookie và bộ nhớ chưa được phân vùng. Các cookie và bộ nhớ này cũng có sẵn khi người dùng truy cập vào iframe dưới dạng trang web cấp cao nhất.

API Truy cập bộ nhớ cho phép cung cấp quyền truy cập vào bộ nhớ và cookie không phân vùng cụ thể mà người dùng cuối không phải chịu gánh nặng, đồng thời vẫn ngăn chặn quyền truy cập vào bộ nhớ và cookie không phân vùng chung chung thường được dùng để theo dõi người dùng.

Trường hợp sử dụng

Một số nội dung nhúng của bên thứ ba yêu cầu quyền truy cập vào cookie hoặc bộ nhớ chưa phân vùng để mang lại trải nghiệm tốt hơn cho người dùng. Điều này sẽ không xảy ra khi cookie của bên thứ ba bị hạn chế và tính năng phân vùng bộ nhớ được bật.

Các trường hợp sử dụng bao gồm:

  • Các tiện ích bình luận được nhúng yêu cầu thông tin chi tiết về phiên đăng nhập.
  • Nút "Thích" trên mạng xã hội yêu cầu thông tin chi tiết về phiên đăng nhập.
  • Tài liệu được nhúng yêu cầu thông tin chi tiết về phiên đăng nhập.
  • Trải nghiệm cao cấp được cung cấp cho một video được nhúng (ví dụ: không hiển thị quảng cáo cho người dùng đã đăng nhập hoặc biết lựa chọn ưu tiên của người dùng về phụ đề hoặc hạn chế một số loại video nhất định).
  • Hệ thống thanh toán được nhúng.

Nhiều trường hợp sử dụng này liên quan đến việc duy trì quyền truy cập đăng nhập trong các iframe được nhúng.

Trường hợp nên sử dụng API truy cập bộ nhớ thay vì các API khác

API Truy cập bộ nhớ là một trong những giải pháp thay thế cho việc sử dụng cookie và bộ nhớ chưa được phân vùng. Vì vậy, bạn cần hiểu rõ thời điểm sử dụng API này so với các API khác. Phương thức này dành cho các trường hợp sử dụng mà cả hai điều sau đều đúng:

  • Người dùng sẽ tương tác với nội dung được nhúng, tức là đó không phải là iframe thụ động hoặc iframe ẩn.
  • Người dùng đã truy cập vào nguồn gốc được nhúng trong ngữ cảnh cấp cao nhất, tức là khi nguồn gốc đó không được nhúng trong một trang web khác.

Có các API thay thế cho nhiều trường hợp sử dụng:

  • Cookies Having Independent Partitioned State (CHIPS) cho phép nhà phát triển chọn sử dụng cookie cho bộ nhớ "phân vùng", với một hộp cookie riêng biệt cho mỗi trang web cấp cao nhất. Ví dụ: một tiện ích trò chuyện trên web của bên thứ ba có thể dựa vào việc đặt cookie để lưu thông tin phiên. Thông tin phiên được lưu trên mỗi trang web, vì vậy, bạn không cần truy cập vào cookie do tiện ích đặt trên các trang web khác cũng nhúng cookie đó. Storage Access API rất hữu ích khi một tiện ích của bên thứ ba được nhúng phụ thuộc vào việc chia sẻ cùng một thông tin trên nhiều nguồn gốc (ví dụ: thông tin chi tiết về phiên đã đăng nhập hoặc lựa chọn ưu tiên).
  • Phân vùng bộ nhớ là một cách để các iframe trên nhiều trang web sử dụng các cơ chế lưu trữ JavaScript hiện có trong khi chia bộ nhớ cơ bản cho mỗi trang web. Điều này giúp ngăn chặn việc cùng một nội dung nhúng trên các trang web khác truy cập vào bộ nhớ được nhúng trong một trang web.
  • Nhóm trang web có liên quan (RWS) là một cách để tổ chức khai báo mối quan hệ giữa các trang web, nhờ đó, trình duyệt cho phép quyền truy cập hạn chế vào cookie và bộ nhớ chưa phân vùng cho các mục đích cụ thể. Các trang web vẫn cần yêu cầu quyền truy cập bằng API Truy cập bộ nhớ, nhưng đối với các trang web trong nhóm, quyền truy cập có thể được cấp mà không cần lời nhắc của người dùng.
  • Quản lý thông tin xác thực liên kết (FedCM) là một phương pháp bảo đảm quyền riêng tư cho các dịch vụ nhận dạng liên kết. API Truy cập bộ nhớ xử lý việc truy cập vào cookie và bộ nhớ chưa được phân vùng sau khi đăng nhập. Đối với một số trường hợp sử dụng, FedCM cung cấp một giải pháp thay thế cho API Truy cập bộ nhớ và có thể được ưu tiên hơn vì có lời nhắc trình duyệt tập trung vào việc đăng nhập hơn. Tuy nhiên, việc sử dụng FedCM thường yêu cầu bạn phải thay đổi thêm mã, chẳng hạn như để hỗ trợ các điểm cuối HTTP.
  • Ngoài ra, còn có các API chống gian lận, liên quan đến quảng cáođo lường. API Truy cập bộ nhớ không nhằm giải quyết những vấn đề đó.

Sử dụng Storage Access API

API Truy cập bộ nhớ có hai phương thức dựa trên lời hứa:

API này cũng tích hợp với Permissions API (API Quyền). Thao tác này cho phép bạn kiểm tra trạng thái của quyền truy cập bộ nhớ trong ngữ cảnh của bên thứ ba, cho biết liệu lệnh gọi đến document.requestStorageAccess() có được tự động cấp hay không:

Sử dụng phương thức hasStorageAccess()

Khi tải lần đầu, trang web có thể sử dụng phương thức hasStorageAccess() để kiểm tra xem quyền truy cập vào cookie của bên thứ ba đã được cấp hay chưa.

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

Quyền truy cập vào bộ nhớ chỉ được cấp cho tài liệu iframe sau khi tài liệu đó gọi requestStorageAccess(),, vì vậy, hasStorageAccess() sẽ luôn trả về giá trị false ban đầu, ngoại trừ khi một tài liệu cùng nguồn gốc khác trong cùng một iframe đã được cấp quyền truy cập. Quyền cấp được giữ nguyên trên các thao tác điều hướng cùng nguồn gốc bên trong iframe, cụ thể là để cho phép tải lại sau khi cấp quyền truy cập cho các trang yêu cầu cookie có trong yêu cầu ban đầu cho tài liệu HTML.

Sử dụng requestStorageAccess()

Nếu không có quyền truy cập, iframe có thể cần yêu cầu quyền truy cập bằng phương thức requestStorageAccess():

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

Trong lần đầu tiên yêu cầu này được đưa ra, người dùng có thể cần phê duyệt quyền truy cập này bằng lời nhắc của trình duyệt, sau đó lời hứa sẽ được phân giải hoặc sẽ từ chối dẫn đến một ngoại lệ nếu await được sử dụng.

Để ngăn chặn hành vi sai trái, lời nhắc này của trình duyệt sẽ chỉ xuất hiện sau khi người dùng tương tác. Đó là lý do tại sao ban đầu, requestStorageAccess() cần được gọi từ trình xử lý sự kiện do người dùng kích hoạt, thay vì ngay khi iframe tải:

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

Nếu cần sử dụng bộ nhớ cục bộ thay vì cookie, bạn có thể làm như sau:

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

Lời nhắc cấp quyền

Khi người dùng nhấp vào nút này lần đầu tiên, lời nhắc của trình duyệt sẽ tự động xuất hiện trong hầu hết các trường hợp, thường là trong thanh địa chỉ. Ảnh chụp màn hình sau đây cho thấy ví dụ về lời nhắc của Chrome, nhưng các trình duyệt khác có giao diện người dùng tương tự:

Lời nhắc cấp quyền cho API Truy cập bộ nhớ của Chrome
Lời nhắc cấp quyền truy cập vào API bộ nhớ của Chrome

Trình duyệt có thể bỏ qua lời nhắc và tự động cấp quyền trong một số trường hợp nhất định:

  • Nếu trang và iframe đã được sử dụng trong 30 ngày qua sau khi chấp nhận lời nhắc.
  • Nếu iframe được nhúng là một phần của Nhóm trang web có liên quan.
  • Nếu FedCM được dùng làm tín hiệu tin cậy để truy cập vào bộ nhớ.
  • Trong Firefox, lời nhắc này cũng sẽ bị bỏ qua đối với các trang web đã biết (những trang web mà bạn đã tương tác ở cấp cao nhất) trong 5 lần thử đầu tiên.

Ngoài ra, phương thức có thể tự động bị từ chối mà không hiển thị lời nhắc trong một số trường hợp nhất định:

  • Nếu trước đây người dùng chưa truy cập và tương tác với trang web sở hữu iframe dưới dạng tài liệu cấp cao nhất, chứ không phải trong iframe. Điều này có nghĩa là Storage Access API chỉ hữu ích cho các trang web được nhúng mà người dùng đã truy cập trước đó trong bối cảnh bên thứ nhất.
  • Nếu phương thức requestStorageAccess() được gọi bên ngoài sự kiện tương tác của người dùng mà không được phê duyệt trước lời nhắc sau khi tương tác.

Mặc dù người dùng sẽ được nhắc trong lần sử dụng đầu tiên, nhưng các lượt truy cập tiếp theo có thể phân giải requestStorageAccess() mà không cần nhắc và không yêu cầu người dùng tương tác trong Chrome và Firefox. Xin lưu ý rằng Safari luôn yêu cầu người dùng tương tác.

Vì quyền truy cập vào cookie và bộ nhớ có thể được cấp mà không cần lời nhắc hoặc tương tác của người dùng, nên bạn thường có thể nhận được quyền truy cập vào cookie hoặc bộ nhớ chưa phân vùng trước khi người dùng tương tác trên các trình duyệt hỗ trợ quyền này (Chrome và Firefox) bằng cách gọi requestStorageAccess() khi tải trang. Điều này có thể cho phép bạn truy cập ngay vào cookie và bộ nhớ chưa được phân vùng, đồng thời mang đến trải nghiệm đầy đủ hơn, ngay cả trước khi người dùng tương tác với iframe. Trong một số trường hợp, việc này có thể mang lại trải nghiệm tốt hơn cho người dùng so với việc chờ người dùng tương tác.

FedCM đóng vai trò là tín hiệu đáng tin cậy cho SAA

FedCM (Quản lý thông tin xác thực liên kết) là một phương pháp bảo vệ quyền riêng tư cho các dịch vụ danh tính liên kết (chẳng hạn như "Đăng nhập bằng...") không dựa vào cookie của bên thứ ba hoặc lệnh chuyển hướng điều hướng.

Khi người dùng đăng nhập vào một Bên phụ thuộc (RP) có một số nội dung được nhúng từ nhà cung cấp danh tính (IdP) bên thứ ba có FedCM, nội dung IdP được nhúng có thể tự động nhận quyền truy cập vào bộ nhớ của các cookie cấp cao nhất chưa được phân vùng của chính nó. Để bật tính năng tự động truy cập vào bộ nhớ bằng FedCM, bạn phải đáp ứng các điều kiện sau:

  • Quy trình xác thực FedCM (trạng thái đăng nhập của người dùng) phải đang hoạt động.
  • RP đã chọn sử dụng bằng cách đặt quyền identity-credentials-get, ví dụ:
<iframe src="https://idp.example" allow="identity-credentials-get"></iframe>

Ví dụ: một iframe idp.example được nhúng trong rp.example. Khi người dùng đăng nhập bằng FedCM, iframe idp.example có thể yêu cầu quyền truy cập vào bộ nhớ cho các cookie cấp cao nhất của chính nó.

rp.example thực hiện lệnh gọi FedCM để đăng nhập người dùng bằng trình cung cấp danh tính 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',
    }],
  },
});

Sau khi người dùng đăng nhập, IdP có thể gọi requestStorageAccess() từ trong khung idp.example, miễn là RP đã cho phép rõ ràng việc này bằng Chính sách về quyền. Trình nhúng sẽ tự động được cấp quyền truy cập vào bộ nhớ cho cookie cấp cao nhất của chính trình nhúng đó mà không cần người dùng kích hoạt hoặc cần có lời nhắc cấp quyền khác:

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

Quyền này sẽ chỉ được cấp tự động miễn là người dùng đăng nhập bằng FedCM. Sau khi quy trình xác thực không hoạt động, các yêu cầu tiêu chuẩn của SAA sẽ áp dụng để cấp quyền truy cập vào bộ nhớ.

Sử dụng truy vấn quyền storage-access

Để kiểm tra xem có thể cấp quyền truy cập mà không cần người dùng tương tác hay không, bạn có thể kiểm tra trạng thái của quyền storage-access và chỉ thực hiện lệnh gọi requestStoreAccess() sớm nếu không cần người dùng thực hiện hành động nào, thay vì gọi lệnh gọi đó và không thành công khi cần tương tác.

Điều này cũng giúp bạn có thể xử lý nhu cầu đưa ra lời nhắc trước bằng cách hiển thị nhiều nội dung khác nhau, chẳng hạn như nút đăng nhập.

Mã sau đây thêm tính năng kiểm tra quyền storage-access vào ví dụ trước:

// 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 trong hộp cát

Khi sử dụng API Truy cập bộ nhớ trong iframe trong hộp cát, bạn phải có các quyền sau đây đối với hộp cát:

  • Cần có allow-storage-access-by-user-activation để cho phép truy cập vào API Truy cập bộ nhớ.
  • Bạn phải có allow-scripts để cho phép sử dụng JavaScript nhằm gọi API.
  • Bạn cần có allow-same-origin để cho phép truy cập vào cookie cùng nguồn gốc và bộ nhớ khác.

Ví dụ:

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

Để được truy cập bằng Storage Access API trong Chrome, bạn phải đặt cookie trên nhiều trang web bằng hai thuộc tính sau:

  • SameSite=None – bắt buộc phải có để đánh dấu cookie là cookie trên nhiều trang web
  • Secure – đảm bảo chỉ có thể truy cập vào cookie do các trang web HTTPS đặt.

Trong Firefox và Safari, cookie được đặt mặc định là SameSite=None và không hạn chế SAA ở cookie Secure, vì vậy, bạn không bắt buộc phải sử dụng các thuộc tính này. Bạn nên nêu rõ thuộc tính SameSite và luôn sử dụng cookie Secure.

Quyền truy cập vào trang cấp cao nhất

API Truy cập bộ nhớ dùng để cho phép truy cập vào cookie của bên thứ ba trong các iframe được nhúng.

Ngoài ra còn có các trường hợp sử dụng khác khi trang cấp cao nhất yêu cầu quyền truy cập vào cookie của bên thứ ba. Ví dụ: hình ảnh hoặc tập lệnh bị hạn chế bởi cookie mà chủ sở hữu trang web có thể muốn đưa trực tiếp vào tài liệu cấp cao nhất thay vì trong iframe. Để giải quyết trường hợp sử dụng này, Chrome đã đề xuất một tiện ích cho API Truy cập bộ nhớ. Tiện ích này sẽ thêm một phương thức requestStorageAccessFor().

Phương thức requestStorageAccessFor()

Hỗ trợ trình duyệt

  • Chrome: 119.
  • Edge: 119.
  • Firefox: không được hỗ trợ.
  • Safari: không được hỗ trợ.

Nguồn

Phương thức requestStorageAccessFor() hoạt động tương tự như requestStorageAccess() nhưng dành cho các tài nguyên cấp cao nhất. Bạn chỉ có thể sử dụng thuộc tính này cho các trang web trong một Nhóm trang web có liên quan để ngăn cấp quyền truy cập chung vào cookie của bên thứ ba.

Để biết thêm thông tin chi tiết về cách sử dụng requestStorageAccessFor(), hãy đọc bài viết Bộ trang web có liên quan: hướng dẫn dành cho nhà phát triển.

Truy vấn quyền top-level-storage-access

Hỗ trợ trình duyệt

  • Chrome: không được hỗ trợ.
  • Edge: không được hỗ trợ.
  • Firefox: không được hỗ trợ.
  • Safari: không được hỗ trợ.

Tương tự như quyền storage-access, có một quyền top-level-storage-access để kiểm tra xem có thể cấp quyền truy cập cho requestStorageAccessFor() hay không.

Storage Access API khác gì khi được sử dụng với RWS?

Khi bạn sử dụng Nhóm trang web có liên quan với API Truy cập bộ nhớ, một số tính năng bổ sung sẽ có sẵn như nêu chi tiết trong bảng sau:

Không có RWS Có RWS
Yêu cầu người dùng thực hiện một cử chỉ để bắt đầu yêu cầu quyền truy cập vào bộ nhớ
Yêu cầu người dùng truy cập vào nguồn gốc bộ nhớ được yêu cầu trong ngữ cảnh cấp cao nhất trước khi cấp quyền truy cập
Có thể bỏ qua lời nhắc dành cho người dùng lần đầu
Không bắt buộc phải gọi requestStorageAccess nếu quyền truy cập đã được cấp trước đó
Tự động cấp quyền truy cập trên các miền khác trong Trang web liên quan
Hỗ trợ requestStorageAccessFor để truy cập vào trang cấp cao nhất
Sự khác biệt giữa việc sử dụng API Truy cập bộ nhớ mà không có và có Nhóm trang web có liên quan

Bản minh hoạ: cài đặt và truy cập cookie

Bản minh hoạ sau đây cho thấy cách truy cập vào một cookie do bạn đặt trong màn hình đầu tiên của bản minh hoạ trong một khung được nhúng trong trang web thứ hai của bản minh hoạ:

storage-access-api-demo.glitch.me

Bản minh hoạ này yêu cầu trình duyệt đã tắt cookie của bên thứ ba:

  • Chrome 118 trở lên với cờ chrome://flags/#test-third-party-cookie-phaseout được đặt và trình duyệt được khởi động lại.
  • Firefox
  • Safari

Bản minh hoạ: thiết lập Bộ nhớ cục bộ

Bản minh hoạ sau đây cho thấy cách truy cập vào các Kênh truyền tin chưa phân vùng từ một iframe của bên thứ ba bằng cách sử dụng API Truy cập bộ nhớ:

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

Bản minh hoạ yêu cầu Chrome 125 trở lên và bật cờ test-third-party-cookie-phaseout.

Tài nguyên