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

Việc chặn cookie của bên thứ ba theo trình duyệt, chế độ cài đặt của người dùng và hoạt động phân vùng bộ nhớ sẽ gây khó khăn cho những trang web và dịch vụ dựa vào cookie và bộ nhớ khác trong ngữ cảnh được nhúng, cũng như các hành trình của người dùng (chẳng hạn 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.
  • Cạnh: 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.

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

Storage Access API là gì?

Storage Access API (API Truy cập bộ nhớ) là một API JavaScript cho phép iframe yêu cầu quyền truy cập vào bộ nhớ khi chế độ cài đặt của trình duyệt từ chối quyền truy cập. Các video nhúng trong những trường hợp sử dụng phụ thuộc vào việc tải tài nguyên trên nhiều trang web có thể dùng API này để yêu cầu người dùng cấp quyền truy cập khi 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 chưa được phân vùng cụ thể với gánh nặng tối thiểu cho người dùng cuối, trong khi vẫn ngăn chặn quyền truy cập vào bộ nhớ và cookie không được phân vùng chung như thường 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 bộ nhớ hoặc cookie không được phân vùng để mang lại trải nghiệm tốt hơn cho người dùng. Tính năng này sẽ không dùng được 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 nhận xét đượ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 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à nội dung đó không phải là iframe thụ động hay iframe ẩn.
  • Người dùng đã truy cập nguồn gốc được nhúng trong ngữ cảnh cấp cao nhất, tức là khi nguồn đó 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 cài đặt cookie để lưu thông tin về phiên trò chuyệ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. Thao tác này ngăn chặn việc truy cập vào bộ nhớ được nhúng trong một trang web bằng chính bộ nhớ được nhúng trên các trang web khác.
  • Bộ trang web có liên quan (RWS) là một cách để một tổ chức khai báo mối quan hệ giữa các trang web để các trình duyệt cho phép truy cập hạn chế vào bộ nhớ và cookie không được 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 người dùng nhắc.
  • Quản lý thông tin xác thực liên kết (FedCM) là một phương pháp bảo vệ quyền riêng tư cho các dịch vụ nhận dạng liên kết. Storage Access API xử lý việc truy cập vào cookie không được phân vùng và bộ nhớ 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 Storage Access API (API Truy cập bộ nhớ) và có thể phù hợp hơn vì có lời nhắc của trình duyệt hướng đến việc đăng nhập hơn. Tuy nhiên, việc áp dụng FedCM thường yêu cầu bạn phải thực hiện các thay đổi bổ sung đối với mã của mình, 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. 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()

Trong lần tải đầu tiên, 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 lần đầu tiên, lời nhắc của trình duyệt sẽ tự động xuất hiện, 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.
  • 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.

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 có tương tác.

Nhờ vậy, bạn có thể xử lý trước nhu cầu đưa ra câu lệnh bằng cách cho hiện nội dung khác (ví dụ 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 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ớ.
  • Cần có allow-scripts để cho phép sử dụng JavaScript để gọi API.
  • 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 để đánh dấu cookie là 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 ở các cookie Secure nên các thuộc tính này là không bắt buộc. 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 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ể dùng tệp này cho các trang web trong một Bộ trang web có liên quan để ngăn việc cấp quyền truy cập chung vào cookie của bên thứ ba.

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

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ó quyền top-level-storage-access để kiểm tra xem có thể cấp quyền truy cập cho requestStorageAccessFor() hay không.

Khi sử dụng cùng RWS, API Truy cập bộ nhớ có gì khác?

Khi sử dụng Bộ trang web có liên quan cùng với Storage Access API, bạn sẽ có thêm một số chức năng bổ sung được nêu chi tiết trong bảng sau:

Không có RWS Có RWS
Cần có cử chỉ của người dùng để 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 cho các miền khác trong một Trang web có 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

Minh hoạ: cài đặt và truy cập vào cookie

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

storage-access-api-demo.glitch.me

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

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

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

Bản minh hoạ sau đây trình bày cách truy cập vào các Kênh truyền phát không được phân vùng từ một iframe của bên thứ ba bằng cách sử dụng Storage Access API:

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

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

Tài nguyên