Thông tin cập nhật của FedCM: Bản dùng thử theo nguyên gốc cho gói API Tiếp tục và cấp tự động API Truy cập bộ nhớ

Kể từ Chrome 126, nhà phát triển có thể bắt đầu chạy bản dùng thử gốc cho một gói các tính năng API quản lý thông tin xác thực liên kết (FedCM) trên máy tính, cho phép một số trường hợp sử dụng Uỷ quyền. Gói này bao gồm API Tiếp tục và API Thông số, cho phép trải nghiệm giống như quy trình uỷ quyền OAuth liên quan đến hộp thoại cấp quyền do nhà cung cấp danh tính (IdP) cung cấp. Gói này cũng bao gồm các thay đổi khác như API Trường, Nhiều configURL và Nhãn tài khoản tuỳ chỉnh. Kể từ Chrome 126, chúng tôi cũng sẽ ra mắt một bản dùng thử gốc cho Storage Access API (SAA) tự động cấp các yêu cầu SAA nếu người dùng đã đăng nhập thành công bằng FedCM trước đây.

Bản dùng thử theo nguyên gốc: Gói FedCM Continuation API

Gói API Tiếp tục FedCM bao gồm nhiều đuôi FedCM:

API tiếp tục

Người dùng đang đăng nhập vào RP, sau đó uỷ quyền thông qua chế độ nút.

Bạn có thể xem bản minh hoạ API trên Glitch.

API Tiếp tục cho phép điểm cuối xác nhận danh tính của IdP trả về một URL mà FedCM sẽ hiển thị để cho phép người dùng tiếp tục quy trình đăng nhập nhiều bước (không bắt buộc). Điều này cho phép IdP yêu cầu người dùng cấp quyền cho bên phụ thuộc (RP) ngoài những quyền có thể cấp trong giao diện người dùng FedCM hiện có, chẳng hạn như quyền truy cập vào tài nguyên phía máy chủ của người dùng.

Thông thường, điểm cuối xác nhận danh tính sẽ trả về một mã thông báo cần thiết để xác thực.

{
  "token": "***********"
}

Tuy nhiên, với API Tiếp tục, điểm cuối xác nhận mã nhận dạng có thể trả về một thuộc tính continue_on bao gồm đường dẫn tuyệt đối hoặc đường dẫn tương đối đến điểm cuối xác nhận mã nhận dạng.

{
  // In the id_assertion_endpoint, instead of returning a typical
  // "token" response, the IdP decides that it needs the user to
  // continue on a pop-up window:
  "continue_on": "/oauth/authorize?scope=..."
}

Ngay khi trình duyệt nhận được phản hồi continue_on, một cửa sổ bật lên mới sẽ mở ra và chuyển người dùng đến đường dẫn đã chỉ định.

Sau khi người dùng tương tác với trang, chẳng hạn như cấp thêm quyền để chia sẻ thông tin bổ sung với RP, trang IdP có thể gọi IdentityProvider.resolve() để phân giải lệnh gọi navigator.credentials.get() ban đầu và trả về một mã thông báo dưới dạng đối số.

document.getElementById('allow_btn').addEventListener('click', async () => {
  let accessToken = await fetch('/generate_access_token.cgi');
  // Closes the window and resolves the promise (that is still hanging
  // in the relying party's renderer) with the value that is passed.
  IdentityProvider.resolve(accessToken);
});

Sau đó, trình duyệt sẽ tự đóng cửa sổ bật lên và trả mã thông báo về cho phương thức gọi API.

Nếu người dùng từ chối yêu cầu, bạn có thể đóng cửa sổ đó bằng cách gọi IdentityProvider.close().

IdentityProvider.close();

Nếu vì lý do nào đó mà người dùng đã thay đổi tài khoản của họ trong cửa sổ bật lên (ví dụ: IdP cung cấp chức năng "chuyển người dùng" hoặc trong trường hợp uỷ quyền), lệnh gọi phân giải sẽ lấy một đối số thứ hai không bắt buộc cho phép thực hiện một số thao tác như:

IdentityProvider.resolve(token, {accountId: '1234');

Parameters API (API Tham số)

Thông số API cho phép RP cung cấp thêm tham số cho điểm cuối của câu nhận định giá trị nhận dạng. Với Parameters API, bên bị hạn chế có thể truyền các tham số bổ sung đến IdP để yêu cầu quyền đối với các tài nguyên ngoài thông tin đăng nhập cơ bản. Người dùng sẽ uỷ quyền cho các quyền này thông qua quy trình trải nghiệm người dùng do IdP kiểm soát, được khởi chạy thông qua API Tiếp tục.

Để sử dụng API này, hãy thêm các tham số vào thuộc tính params dưới dạng đối tượng trong lệnh gọi navigator.credentials.get().

let {token} = await navigator.credentials.get({
  identity: {
    providers: [{
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      // Key/value pairs that need to be passed from the
      // RP to the IdP but that don't really play any role with
      // the browser.
      params: {
        IDP_SPECIFIC_PARAM: '1',
        foo: 'BAR',
        ETC: 'MOAR',
        scope: 'calendar.readonly photos.write',
      }
    },
  }
});

Tên thuộc tính trong đối tượng params được thêm vào trước bằng param_. Trong ví dụ trên, thuộc tính tham số chứa IDP_SPECIFIC_PARAM'1', foo'BAR', ETC'MOAR'scope'calendar.readonly photos.write'. Lệnh này sẽ được dịch là param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write trong phần nội dung HTTP của yêu cầu:

POST /fedcm_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false&param_IDP_SPECIFIC_PARAM=1&param_foo=BAR&param_ETC=MOAR&param_scope=calendar.readonly%20photos.write

Tự động nhận quyền

Nhìn chung, đối với người dùng, việc yêu cầu cấp quyền khi cần thiết sẽ hữu ích nhất, thay vì khi nhà phát triển cảm thấy rằng đó là dễ triển khai nhất. Ví dụ: yêu cầu quyền truy cập vào camera khi người dùng sắp chụp ảnh sẽ được ưu tiên hơn là yêu cầu cấp quyền ngay khi người dùng truy cập vào trang web. Phương pháp tương tự cũng áp dụng cho tài nguyên máy chủ. Chỉ yêu cầu quyền khi người dùng cần. Phương thức này được gọi là "uỷ quyền động".

Để yêu cầu uỷ quyền một cách linh động bằng FedCM, IdP có thể:

  1. Gọi navigator.credentials.get() bằng các tham số bắt buộc mà IdP có thể hiểu được, chẳng hạn như scope.
  2. Điểm cuối xác nhận mã nhận dạng xác nhận người dùng đã đăng nhập và phản hồi bằng một URL continue_on.
  3. Trình duyệt sẽ mở một cửa sổ bật lên có trang quyền của IdP để yêu cầu cấp thêm quyền phù hợp với phạm vi được yêu cầu.
  4. Sau khi được IdP uỷ quyền thông qua IdentityProvider.resolve(), cửa sổ sẽ đóng và lệnh gọi navigator.credentials.get() ban đầu của RP sẽ nhận được mã thông báo hoặc mã uỷ quyền có liên quan để RP có thể trao đổi mã đó với mã truy cập thích hợp.

API Fields

API trường cho phép RP khai báo các thuộc tính tài khoản cần yêu cầu từ IdP để trình duyệt có thể hiển thị giao diện người dùng thông tin công bố thích hợp trong hộp thoại FedCM; IdP có trách nhiệm đưa các trường được yêu cầu vào mã thông báo được trả về. Hãy xem xét việc yêu cầu này một "hồ sơ cơ bản" trong OpenID Connect so với "phạm vi" trong OAuth.

Thông báo công bố ở chế độ tiện ích.
Thông báo công bố ở chế độ tiện ích.
Thông báo công bố ở chế độ nút.
Thông báo công bố ở chế độ nút.

Để sử dụng API Trường, hãy thêm các tham số vào thuộc tính fields dưới dạng một mảng trong lệnh gọi navigator.credentials.get(). Các trường hiện có thể chứa 'name', 'email''picture', nhưng có thể mở rộng để thêm nhiều giá trị hơn trong tương lai.

Yêu cầu với fields sẽ có dạng như sau:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: ['name', 'email', 'picture'],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

Yêu cầu HTTP đến điểm cuối xác nhận mã nhận dạng bao gồm tham số fields do RP chỉ định, với tham số disclosure_text_shown được đặt là true nếu đây không phải là người dùng cũ và các trường mà trình duyệt đã công bố cho người dùng trong tham số disclosure_shown_for:

POST /id_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=true&fields=email,name,picture&disclosure_shown_for=email,name,picture

Nếu RP cần quyền truy cập vào bất kỳ dữ liệu bổ sung nào từ IdP, chẳng hạn như quyền truy cập vào một lịch, thì bạn nên xử lý việc này bằng một thông số tuỳ chỉnh như đã đề cập ở trên. IdP trả về một URL continue_on để yêu cầu quyền.

Nếu fields là một mảng trống, thì yêu cầu sẽ có dạng như sau:

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      fields: [],
      clientId: '1234',
      configURL: 'https://idp.example/fedcm.json',
      params: {
        scope: 'drive.readonly calendar.readonly',
      }
    },
  }
  mediation: 'optional',
});

Nếu fields là một mảng trống, thì tác nhân người dùng sẽ bỏ qua giao diện người dùng công bố thông tin.

Thông báo công bố không hiển thị ở chế độ tiện ích. Trong quy trình nút, giao diện người dùng thông tin công bố sẽ bị bỏ qua hoàn toàn.
Thông báo công bố không xuất hiện ở chế độ tiện ích. Trong quy trình của nút, giao diện người dùng của thông tin công bố bị bỏ qua hoàn toàn.

Điều này xảy ra ngay cả khi phản hồi từ điểm cuối tài khoản không chứa mã ứng dụng khớp với RP trong approved_clients.

Trong trường hợp này, disclosure_text_shown được gửi đến điểm cuối của câu nhận định mã nhận dạng sẽ là false trong phần nội dung HTTP:

POST /id_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false

Nhiều configURLs

Nhiều configURL cho phép IdP lưu trữ nhiều tệp cấu hình cho một IdP, bằng cách chỉ định accounts_endpointlogin_url trong tệp well-known giống như các tệp cấu hình.

Nếu accounts_endpointlogin_url được thêm vào tệp well-known, thì provider_urls sẽ bị bỏ qua để IdP có thể hỗ trợ nhiều tệp cấu hình. Nếu không, provider_urls sẽ tiếp tục có hiệu lực để tương thích ngược.

Tệp well-known hỗ trợ nhiều configURL có thể có dạng như sau:

{
  "provider_urls": [ "https://idp.example/fedcm.json" ],
  "accounts_endpoint": "https://idp.example/accounts",
  "login_url": "https://idp.example/login"
}

Điều này cho phép chúng tôi:

  1. Duy trì khả năng tương thích ngược và tiến với các tệp phổ biến hiện có và phiên bản cũ của trình duyệt đã được triển khai tự nhiên.
  2. Có số lượng tệp cấu hình tuỳ ý, miễn là tất cả các tệp đó đều trỏ đến cùng một accounts_endpointlogin_url.
  3. Không có cơ hội để thêm entropy vào yêu cầu tìm nạp đã xác thực được gửi đến accounts_endpoint, vì bạn phải chỉ định entropy ở cấp "well-known".

Bạn không bắt buộc phải hỗ trợ nhiều configURL và các phương thức triển khai FedCM hiện có có thể giữ nguyên.

Nhãn tài khoản tùy chỉnh

Nhãn tài khoản tuỳ chỉnh cho phép các IDP FedCM chú thích tài khoản để các RP có thể lọc tài khoản bằng cách chỉ định nhãn trong tệp cấu hình. Bạn có thể lọc theo cách tương tự bằng cách sử dụng API gợi ý miềnAPI gợi ý đăng nhập bằng cách chỉ định các API đó trong lệnh gọi navigator.credentials.get(), nhưng Nhãn tài khoản tuỳ chỉnh có thể lọc người dùng bằng cách chỉ định tệp cấu hình. Điều này đặc biệt hữu ích khi sử dụng nhiều configURL. Nhãn tài khoản tuỳ chỉnh cũng khác ở chỗ chúng được cung cấp từ máy chủ IdP, thay vì từ RP, chẳng hạn như gợi ý đăng nhập hoặc miền.

Ví dụ:

IdP hỗ trợ hai configURL tương ứng cho người tiêu dùng và doanh nghiệp. Tệp cấu hình người dùng có nhãn 'consumer' và tệp cấu hình doanh nghiệp có nhãn 'enterprise'.

Với cách thiết lập như vậy, tệp phổ biến sẽ bao gồm accounts_endpointlogin_url để cho phép nhiều configURL.

{
  "provider_urls": [ "https://idp.example/fedcm.json" ],
  "accounts_endpoint": "https://idp.example/accounts",
  "login_url": "https://idp.example/login"
}

Khi accounts_endpoint được cung cấp trong tệp well-known, provider_urls sẽ bị bỏ qua. RP có thể trỏ trực tiếp vào các tệp cấu hình tương ứng trong lệnh gọi navigator.credentials.get().

Tệp cấu hình của người dùng nằm tại https://idp.example/fedcm.json, bao gồm cả thuộc tính accounts chỉ định 'consumer' bằng include.

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "consumer"
  }
}

Tệp cấu hình doanh nghiệp nằm tại https://idp.example/enterprise/fedcm.json, bao gồm cả thuộc tính accounts chỉ định 'enterprise' bằng include.

{
  "accounts_endpoint": "https://idp.example/accounts",
  "client_metadata_endpoint": "/enterprise/client_metadata",
  "login_url": "https://idp.example/login",
  "id_assertion_endpoint": "/assertion",
  "accounts": {
    "include": "enterprise"
  }
}

Điểm cuối tài khoản phổ biến của IdP (trong ví dụ này là https://idp.example/accounts) trả về danh sách các tài khoản có chứa thuộc tính nhãn được chỉ định labels trong một mảng cho mỗi tài khoản. Sau đây là ví dụ về phản hồi cho một người dùng có hai tài khoản. Một phiên bản dành cho người tiêu dùng và phiên bản còn lại dành cho doanh nghiệp:

{
 "accounts": [{
   "id": "123",
   "given_name": "John",
   "name": "John Doe",
   "email": "john_doe@idp.example",
   "picture": "https://idp.example/profile/123",
   "labels": ["consumer"]
  }], [{
   "id": "4567",
   "given_name": "Jane",
   "name": "Jane Doe",
   "email": "jane_doe@idp.example",
   "picture": "https://idp.example/profile/4567",
   "labels": ["enterprise"]
  }]
}

Khi muốn cho phép người dùng 'enterprise' đăng nhập, RP có thể chỉ định 'enterprise' configURL 'https://idp.example/enterprise/fedcm.json' trong lệnh gọi navigator.credentials.get():

let { token } = await navigator.credentials.get({
  identity: {
    providers: [{
      clientId: '1234',
      nonce: '234234',
      configURL: 'https://idp.example/enterprise/fedcm.json',
    },
  }
});

Do đó, người dùng chỉ có thể đăng nhập bằng mã tài khoản '4567'. Trình duyệt đã tự động ẩn mã tài khoản của '123' để người dùng sẽ không được cung cấp một tài khoản không được IdP hỗ trợ trên trang web này.

Bản dùng thử theo nguyên gốc: FedCM làm tín hiệu tin cậy cho Storage Access API

Chrome 126 đang bắt đầu bản dùng thử theo nguyên gốc của FedCM làm tín hiệu tin cậy cho API Truy cập bộ nhớ. Với thay đổi này, việc cấp quyền trước đó thông qua FedCM sẽ trở thành lý do hợp lệ để tự động phê duyệt yêu cầu truy cập bộ nhớ của API Truy cập bộ nhớ.

Điều này rất hữu ích khi một iframe được nhúng muốn truy cập vào các tài nguyên được cá nhân hoá: chẳng hạn như nếu idp.example được nhúng trong rp.example và cần hiển thị tài nguyên được cá nhân hoá. Nếu trình duyệt hạn chế quyền truy cập vào cookie của bên thứ ba, ngay cả khi người dùng đăng nhập vào rp.example bằng idp.example bằng FedCM, thì iframe idp.example nhúng sẽ không thể yêu cầu tài nguyên được cá nhân hoá vì các yêu cầu sẽ không bao gồm cookie của bên thứ ba.

Để đạt được điều này, idp.example cần có quyền truy cập vào bộ nhớ thông qua iframe được nhúng trên trang web và điều này chỉ có thể nhận được thông qua lời nhắc cấp quyền.

Với FedCM làm tín hiệu tin cậy cho API Truy cập bộ nhớ, các bước kiểm tra quyền của API Truy cập bộ nhớ không chỉ chấp nhận việc cấp quyền do lời nhắc truy cập bộ nhớ cấp mà còn chấp nhận việc cấp quyền do lời nhắc FedCM cấp.

// In top-level rp.example:

// Ensure FedCM permission has been granted.
const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/fedcm.json',
      clientId: '123',
    }],
  },
  mediation: 'optional',
});

// In an embedded IdP iframe:

// No user gesture is needed to call this, and the call will be auto-granted.
await document.requestStorageAccess();

// This returns `true`.
const hasAccess = await document.hasStorageAccess();

Sau khi người dùng đăng nhập bằng FedCM, quyền này sẽ tự động được cấp miễn là quá trình xác thực FedCM đang hoạt động. Điều này có nghĩa là sau khi người dùng bị ngắt kết nối, việc yêu cầu quyền sẽ hiển thị lời nhắc.

Tham gia thử nghiệm về nguồn gốc

Bạn có thể dùng thử gói API Tiếp tục FedCM trên thiết bị bằng cách bật cờ Chrome chrome://flags#fedcm-authz trên Chrome 126 trở lên. Bạn cũng có thể dùng thử FedCM làm tín hiệu tin cậy cho API Truy cập bộ nhớ trên thiết bị bằng cách bật #fedcm-with-storage-access-api trên Chrome 126 trở lên.

Những tính năng này cũng được cung cấp dưới dạng bản dùng thử theo nguyên gốc. Bản dùng thử theo nguyên gốc cho phép bạn dùng thử các tính năng mới và đưa ra ý kiến phản hồi về khả năng hữu dụng, tính thực tế và hiệu quả của các tính năng đó. Để biết thêm thông tin, hãy xem bài viết Bắt đầu thử nghiệm nguồn gốc.

Để dùng thử bản dùng thử nguồn gốc gói API Tiếp tục của FedCM, hãy tạo hai mã thông báo dùng thử nguồn gốc:

Nếu bạn muốn bật API Tiếp tục cùng với luồng nút, hãy bật cả bản dùng thử nguồn gốc API Chế độ nút:

Cách dùng thử FedCM làm tín hiệu tin cậy cho bản dùng thử theo nguyên gốc Storage Access API:

Bản dùng thử theo nguyên gốc gói Continuation API và FedCM dưới dạng tín hiệu tin cậy cho bản dùng thử theo nguyên gốc Storage Access API có trong Chrome 126.

Đăng ký bản dùng thử nguồn gốc bên thứ ba cho RP

  1. Truy cập vào trang đăng ký bản dùng thử theo nguyên gốc.
  2. Nhấp vào nút Register (Đăng ký) rồi điền thông tin vào biểu mẫu để yêu cầu mã thông báo.
  3. Nhập nguồn gốc của IdP là Nguồn gốc web.
  4. Kiểm tra tính năng So khớp bên thứ ba để chèn mã thông báo bằng JavaScript trên các nguồn gốc khác.
  5. Nhấp vào Gửi.
  6. Nhúng mã thông báo đã phát hành trên trang web của bên thứ ba.

Để nhúng mã thông báo trên trang web của bên thứ ba, hãy thêm mã sau vào thư viện JavaScript hoặc SDK của IdP được phân phát từ nguồn gốc của IdP.

const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);

Thay thế TOKEN_GOES_HERE bằng mã thông báo của riêng bạn.