Tìm hiểu cách sử dụng FedCM để liên kết danh tính nhằm bảo đảm quyền riêng tư.
FedCM (Quản lý thông tin xác thực liên kết) là một giải pháp bảo đảm quyền riêng tư phương thức tiếp cận với các dịch vụ nhận dạng được liên kết (chẳng hạn như "Đăng nhập bằng..."), trong đó Người dùng có thể đăng nhập vào các trang web mà không phải chia sẻ thông tin cá nhân của họ với hoặc trang web.
Để tìm hiểu thêm về các trường hợp sử dụng, luồng người dùng và lộ trình API của FedCM, hãy tham khảo giới thiệu về API FedCM.
Môi trường phát triển FedCM
Bạn cần có một bối cảnh bảo mật (HTTPS hoặc máy chủ cục bộ) trên cả IdP và RP trong Chrome để sử dụng FedCM.
Gỡ lỗi mã trong Chrome trên Android
Thiết lập và chạy một máy chủ cục bộ để gỡ lỗi mã FedCM của bạn. Bạn có thể truy cập vào máy chủ này trong Chrome trên thiết bị Android kết nối bằng cáp USB có cổng chuyển tiếp.
Bạn có thể sử dụng Công cụ cho nhà phát triển trên máy tính để gỡ lỗi Chrome trên Android bằng cách làm theo hướng dẫn tại Gỡ lỗi từ xa cho Android thiết bị.
Chặn cookie của bên thứ ba trên Chrome
![Mô phỏng việc loại bỏ cookie của bên thứ ba bằng cách định cấu hình Chrome để chặn các cookie này](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/simulate-third-party-cook-8416bea1ab2b.png?authuser=9&hl=vi)
Bạn có thể thử nghiệm cách FedCM hoạt động mà không cần cookie của bên thứ ba trên Chrome trước khi được thực thi.
Để chặn cookie của bên thứ ba, hãy sử dụng chế độ Ẩn danh
hoặc chọn "Chặn
cookie của bên thứ ba" trong phần cài đặt của máy tính tại chrome://settings/cookies
hoặc trên
thiết bị di động bằng cách chuyển đến phần Cài đặt > Cài đặt trang web > Cookie.
Sử dụng API FedCM
Bạn tích hợp với FedCM bằng cách tạo một tệp phổ biến, tệp cấu hình và điểm cuối cho tài khoản danh sách, chứng thực và siêu dữ liệu ứng dụng (không bắt buộc).
Từ đó, FedCM hiển thị các API JavaScript mà RP có thể dùng để ký trong nhà cung cấp danh tính (IdP).
Tạo một tệp phổ biến
Để ngăn công cụ theo dõi lạm dụng
API, thì một tệp phổ biến phải
phân phát từ /.well-known/web-identity
trong số
eTLD+1 của
IdP (nhà cung cấp danh tính).
Ví dụ: nếu điểm cuối của IdP được phân phát trong
https://accounts.idp.example/
, các tài sản này phải phân phát một tệp phổ biến tại
https://idp.example/.well-known/web-identity
cũng như một cấu hình nhà cung cấp danh tính (IdP)
. Dưới đây là một ví dụ về nội dung tệp phổ biến:
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
Tệp JSON phải chứa thuộc tính provider_urls
với một mảng IdP
config URL có thể được chỉ định làm một phần đường dẫn của
configURL
ở navigator.credentials.get
theo bên bị hạn chế. Số lượng
Các chuỗi URL trong mảng được giới hạn ở 1 nhưng điều này có thể thay đổi theo
ý kiến phản hồi trong tương lai.
Tạo tệp cấu hình IdP và điểm cuối
Tệp cấu hình IdP cung cấp danh sách các điểm cuối bắt buộc cho trình duyệt. IdPs
sẽ lưu trữ tệp cấu hình này cũng như các điểm cuối và URL được yêu cầu. Tất cả tệp JSON
câu trả lời phải được phân phát với loại nội dung application/json
.
URL của tệp cấu hình được xác định bởi các giá trị được cung cấp cho
Lệnh gọi navigator.credentials.get
được thực thi trên một RP.
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
Chỉ định một URL đầy đủ cho vị trí tệp cấu hình IdP làm configURL
. Thời gian
navigator.credentials.get()
được gọi trên RP, trình duyệt
tìm nạp tệp cấu hình bằng yêu cầu GET
mà không có tiêu đề Origin
hoặc
Tiêu đề Referer
. Yêu cầu này không có cookie và không tuân theo lệnh chuyển hướng.
Việc này giúp ngăn chặn một cách hiệu quả IdP biết được ai đã đưa ra yêu cầu và
RP đang cố gắng kết nối. Ví dụ:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
Trình duyệt cần có phản hồi JSON từ IdP, trong đó bao gồm những thông tin sau thuộc tính:
Thuộc tính | Mô tả |
---|---|
accounts_endpoint (bắt buộc) |
URL cho điểm cuối của tài khoản. |
client_metadata_endpoint (không bắt buộc) |
URL cho điểm cuối siêu dữ liệu ứng dụng. |
id_assertion_endpoint (bắt buộc) |
URL dành cho điểm cuối xác nhận mã nhận dạng. |
disconnect (không bắt buộc) |
URL cho điểm cuối ngắt kết nối. |
login_url (bắt buộc) |
URL trang đăng nhập để người dùng đăng nhập vào IdP. |
branding (không bắt buộc) |
Đối tượng chứa nhiều lựa chọn xây dựng thương hiệu. |
branding.background_color (không bắt buộc) |
Tuỳ chọn xây dựng thương hiệu đặt màu nền của thông báo "Continue as..." (Tiếp tục dưới dạng...) . Hãy sử dụng cú pháp CSS phù hợp, cụ thể là
hex-color !
hsl() ,
rgb() hoặc
named-color . |
branding.color (không bắt buộc) |
Tuỳ chọn xây dựng thương hiệu giúp đặt màu văn bản của thông báo "Continue as..." (Tiếp tục dưới dạng...) . Hãy sử dụng cú pháp CSS phù hợp, cụ thể là
hex-color !
hsl() ,
rgb() hoặc
named-color . |
branding.icons (không bắt buộc) |
Tuỳ chọn xây dựng thương hiệu để đặt đối tượng biểu tượng, xuất hiện trong hộp thoại đăng nhập. Đối tượng biểu tượng là một mảng có hai tham số:
|
RP có thể sửa đổi chuỗi trong giao diện người dùng hộp thoại FedCM thông qua giá trị identity.context
cho navigator.credentials.get()
để phù hợp với phương thức xác thực định sẵn
ngữ cảnh. Thuộc tính không bắt buộc có thể là một trong các thuộc tính "signin"
(mặc định), "signup"
,
"use"
hoặc "continue"
.
![Cách áp dụng nhãn hiệu cho hộp thoại FedCM](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/RZwmFnyJChjlki8QsnBB.png?authuser=9&hl=vi)
Dưới đây là một nội dung phản hồi mẫu từ IdP:
{
"accounts_endpoint": "/accounts.php",
"client_metadata_endpoint": "/client_metadata.php",
"id_assertion_endpoint": "/assertion.php",
"disconnect_endpoint": "/disconnect.php",
"login_url": "/login",
"branding": {
"background_color": "green",
"color": "#FFEEAA",
"icons": [{
"url": "https://idp.example/icon.ico",
"size": 25
}]
}
}
Sau khi trình duyệt tìm nạp tệp cấu hình, trình duyệt sẽ gửi các yêu cầu tiếp theo đến Điểm cuối của IdP:
![Điểm cuối của IdP (nhà cung cấp danh tính)](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/idp-endpoints-a67327f46da51.png?authuser=9&hl=vi)
Điểm cuối của tài khoản
Điểm cuối tài khoản của IdP trả về danh sách các tài khoản mà người dùng hiện đang đăng nhập trên IdP. Nếu IdP hỗ trợ nhiều tài khoản, thì thao tác này điểm cuối sẽ trả về tất cả tài khoản đã đăng nhập.
Trình duyệt gửi yêu cầu GET
có cookie có SameSite=None
, nhưng không có
tham số client_id
, tiêu đề Origin
hoặc tiêu đề Referer
. Chiến dịch này
ngăn chặn một cách hiệu quả IdP biết được RP mà người dùng đang cố gắng ký
vào. Ví dụ:
GET /accounts.php HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
Khi nhận được yêu cầu, máy chủ cần:
- Xác minh rằng yêu cầu có chứa tiêu đề HTTP
Sec-Fetch-Dest: webidentity
. - So khớp cookie của phiên hoạt động với mã nhận dạng của các tài khoản đã đăng nhập.
- Trả lời kèm theo danh sách tài khoản.
Trình duyệt mong đợi nhận được phản hồi JSON bao gồm thuộc tính accounts
cùng với một mảng thông tin tài khoản với các thuộc tính sau:
Thuộc tính | Mô tả |
---|---|
id (bắt buộc) |
Mã nhận dạng duy nhất của người dùng. |
name (bắt buộc) |
Họ và tên của người dùng. |
email (bắt buộc) |
Địa chỉ email của người dùng. |
given_name (không bắt buộc) |
Tên của người dùng. |
picture (không bắt buộc) |
URL của hình đại diện của người dùng. |
approved_clients (không bắt buộc) |
Một mảng mã ứng dụng khách RP mà người dùng đã đăng ký. |
login_hints (không bắt buộc) |
Một mảng gồm tất cả các loại bộ lọc mà IdP hỗ trợ để chỉ định
một tài khoản. Bên bị hạn chế có thể gọi navigator.credentials.get()
với thuộc tính loginHint để
hiển thị có chọn lọc tài khoản được chỉ định. |
domain_hints (không bắt buộc) |
Một mảng gồm tất cả các miền liên kết với tài khoản. Bên bị hạn chế có thể
gọi navigator.credentials.get() bằng
Thuộc tính domainHint để lọc
tài khoản. |
Ví dụ về nội dung phản hồi:
{
"accounts": [{
"id": "1234",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"approved_clients": ["123", "456", "789"],
"login_hints": ["demo1", "demo1@idp.example"]
}, {
"id": "5678",
"given_name": "Johnny",
"name": "Johnny",
"email": "johnny@idp.example",
"picture": "https://idp.example/profile/456",
"approved_clients": ["abc", "def", "ghi"],
"login_hints": ["demo2", "demo2@idp.example"],
"domain_hints": ["corp.example"]
}]
}
Nếu người dùng chưa đăng nhập, hãy phản hồi bằng HTTP 401 (Chưa được uỷ quyền).
Danh sách tài khoản được trả về được trình duyệt sử dụng và sẽ không có sẵn cho bên bị hạn chế.
Điểm cuối siêu dữ liệu ứng dụng
Điểm cuối siêu dữ liệu ứng dụng của IdP sẽ trả về siêu dữ liệu của bên đáng tin cậy, chẳng hạn như chính sách quyền riêng tư và điều khoản dịch vụ của bên bị hạn chế. Bên bị hạn chế phải cung cấp đường liên kết đến chính sách quyền riêng tư và điều khoản dịch vụ cho IdP (nhà cung cấp danh tính). Những đường liên kết này hiển thị trong hộp thoại đăng nhập khi người dùng chưa đăng ký trên RP với nhà cung cấp danh tính (IdP).
Trình duyệt gửi yêu cầu GET
bằng client_id
navigator.credentials.get
không có cookie. Ví dụ:
GET /client_metadata.php?client_id=1234 HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Accept: application/json
Sec-Fetch-Dest: webidentity
Khi nhận được yêu cầu, máy chủ cần:
- Xác định RP cho
client_id
. - Trả lời kèm theo siêu dữ liệu ứng dụng.
Các thuộc tính dành cho điểm cuối siêu dữ liệu của ứng dụng bao gồm:
Thuộc tính | Mô tả |
---|---|
privacy_policy_url (không bắt buộc) |
URL chính sách quyền riêng tư của RP. |
terms_of_service_url (không bắt buộc) |
URL của điều khoản dịch vụ của RP. |
Trình duyệt mong đợi nhận được phản hồi JSON từ điểm cuối:
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html",
}
Siêu dữ liệu ứng dụng được trả về được trình duyệt sử dụng và sẽ không được dành cho RP.
Điểm cuối xác nhận mã nhận dạng
Điểm cuối xác nhận mã nhận dạng của IdP sẽ trả về một câu nhận định cho người dùng đã đăng nhập của họ.
Khi người dùng đăng nhập vào một trang web bên bị hạn chế bằng navigator.credentials.get()
thì trình duyệt sẽ gửi một yêu cầu POST
có cookie kèm theo
SameSite=None
và loại nội dung từ application/x-www-form-urlencoded
đến
điểm cuối này với thông tin sau:
Thuộc tính | Mô tả |
---|---|
client_id (bắt buộc) |
Giá trị nhận dạng ứng dụng khách của bên bị hạn chế. |
account_id (bắt buộc) |
Mã nhận dạng duy nhất của người dùng đang đăng nhập. |
nonce (không bắt buộc) |
Số chỉ dùng một lần yêu cầu, do RP cung cấp. |
disclosure_text_shown |
Kết quả bằng một chuỗi "true" hoặc "false" (thay vì một boolean). Kết quả sẽ là "false" nếu văn bản thông tin công bố không xuất hiện. Điều này xảy ra khi mã ứng dụng khách của RP được đưa vào danh sách thuộc tính approved_clients của phản hồi từ điểm cuối của tài khoản hoặc nếu trình duyệt đã quan sát thấy một khoảnh khắc đăng ký trong quá khứ mà không có approved_clients . |
is_auto_selected |
Nếu bạn thực hiện tự động xác thực lại trên RP, is_auto_selected sẽ cho biết "true" . Nếu không thì "false" . Điều này rất hữu ích trong việc hỗ trợ thêm các tính năng liên quan đến bảo mật. Ví dụ: một số người dùng có thể thích cấp bảo mật cao hơn, đòi hỏi người dùng phải dàn xếp rõ ràng khi xác thực. Nếu một IdP nhận được yêu cầu về mã thông báo mà không qua quá trình dàn xếp đó, thì họ có thể xử lý yêu cầu theo cách khác. Ví dụ: trả về một mã lỗi để RP có thể gọi lại API FedCM bằng mediation: required . |
Tiêu đề HTTP mẫu:
POST /assertion.php HTTP/1.1
Host: accounts.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=Ct60bD&disclosure_text_shown=true&is_auto_selected=true
Khi nhận được yêu cầu, máy chủ cần:
- Phản hồi yêu cầu bằng CORS (Tài nguyên trên nhiều nguồn gốc) Chia sẻ).
- Xác minh rằng yêu cầu có chứa tiêu đề HTTP
Sec-Fetch-Dest: webidentity
. - So khớp tiêu đề
Origin
với nguồn gốc RP doclient_id
xác định. Từ chối nếu chúng không khớp. - So khớp
account_id
với mã của tài khoản đã đăng nhập. Từ chối nếu chúng không khớp với nhau. - Trả lời bằng mã thông báo. Nếu yêu cầu bị từ chối, hãy phản hồi kèm theo lỗi .
Cách cấp mã thông báo sẽ phụ thuộc vào IdP, nhưng nhìn chung, mã đó được ký bằng
các thông tin như mã tài khoản, mã ứng dụng khách, nguồn gốc của nhà phát hành, nonce
, để
bên bị hạn chế có thể xác minh rằng mã thông báo đó là thật.
Trình duyệt dự kiến sẽ nhận được phản hồi JSON bao gồm thuộc tính sau:
Thuộc tính | Mô tả |
---|---|
token (bắt buộc) |
Mã thông báo là một chuỗi chứa các tuyên bố về việc xác thực. |
{
"token": "***********"
}
Trình duyệt chuyển mã thông báo được trả về cho RP để RP có thể xác thực.
Trả về phản hồi lỗi
id_assertion_endpoint
cũng có thể trả về "lỗi"
phản hồi, có hai trường không bắt buộc:
code
: IdP có thể chọn một trong các lỗi đã biết từ OAuth 2.0 lỗi cụ thể danh sách (invalid_request
,unauthorized_client
,access_denied
,server_error
vàtemporarily_unavailable
) hoặc sử dụng chuỗi tuỳ ý. Nếu có, Chrome hiển thị giao diện người dùng lỗi kèm theo thông báo lỗi chung và truyền mã đó đến RP.url
: Mã này xác định một trang web mà con người có thể đọc được, chứa thông tin về cung cấp thêm thông tin về lỗi cho người dùng. Trường này rất hữu ích cho người dùng vì trình duyệt không thể cung cấp thông báo lỗi nhiều định dạng trong một giao diện người dùng gốc. Ví dụ: đường liên kết cho các bước tiếp theo, thông tin liên hệ của bộ phận dịch vụ khách hàng thông tin, v.v. Nếu người dùng muốn tìm hiểu thêm về thông tin chi tiết về lỗi và cách khắc phục, họ có thể truy cập trang được cung cấp từ giao diện người dùng của trình duyệt để chi tiết hơn. URL này phải thuộc cùng một trang web với IdPconfigURL
.
// id_assertion_endpoint response
{
"error" : {
"code": "access_denied",
"url" : "https://idp.example/error?type=access_denied"
}
}
Ngắt kết nối thiết bị đầu cuối
Khi gọi IdentityCredential.disconnect()
, trình duyệt sẽ gửi một nguồn gốc khác
Yêu cầu POST
có cookie có SameSite=None
và loại nội dung
application/x-www-form-urlencoded
đến điểm cuối ngắt kết nối này bằng
các thông tin sau:
Thuộc tính | Mô tả |
---|---|
account_hint |
Gợi ý về tài khoản IdP. |
client_id |
Giá trị nhận dạng ứng dụng khách của bên bị hạn chế. |
POST /disconnect.php HTTP/1.1
Host: idp.example
Origin: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity
account_hint=account456&client_id=rp123
Khi nhận được yêu cầu, máy chủ cần:
- Phản hồi yêu cầu bằng CORS (Tài nguyên trên nhiều nguồn gốc) Chia sẻ).
- Xác minh rằng yêu cầu có chứa tiêu đề HTTP
Sec-Fetch-Dest: webidentity
. - So khớp tiêu đề
Origin
với nguồn gốc RP doclient_id
xác định. Từ chối nếu chúng không khớp. - So khớp
account_hint
với mã nhận dạng của các tài khoản đã đăng nhập. - Ngắt kết nối tài khoản người dùng khỏi bên bị hạn chế.
- Phản hồi cho trình duyệt bằng thông tin tài khoản người dùng đã được xác định trong tệp JSON .
Ví dụ về tải trọng JSON phản hồi sẽ có dạng như sau:
{
"account_id": "account456"
}
Thay vào đó, nếu IdP muốn trình duyệt ngắt kết nối tất cả tài khoản đã liên kết với
RP, truyền một chuỗi không khớp với bất kỳ mã tài khoản nào, ví dụ: "*"
.
URL đăng nhập
Với API trạng thái đăng nhập, IdP phải thông báo cho người dùng
trạng thái đăng nhập vào trình duyệt. Tuy nhiên, trạng thái có thể không đồng bộ, chẳng hạn như
khi phiên hết hạn. Trong trường hợp như vậy,
trình duyệt có thể cho phép người dùng đăng nhập vào IdP (nhà cung cấp danh tính) một cách linh động thông qua trang đăng nhập
URL được chỉ định bằng login_url
của tệp cấu hình idp.
Hộp thoại FedCM hiển thị thông báo đề xuất đăng nhập, như được hiển thị trong hình ảnh tiếp theo.
![A](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-120-1.png?authuser=9&hl=vi)
Khi người dùng nhấp vào nút Tiếp tục, trình duyệt sẽ mở cửa sổ bật lên cho trang đăng nhập của IdP.
![Một](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-120-2.png?authuser=9&hl=vi)
Hộp thoại là một cửa sổ trình duyệt thông thường có cookie của bên thứ nhất. Bất kể thế nào diễn ra trong hộp thoại tuỳ thuộc vào IdP và không có tay điều khiển cửa sổ nào để gửi một yêu cầu thông báo trên nhiều nguồn gốc đến trang RP. Sau khi người dùng đã đăng nhập, IdP cần:
- Gửi tiêu đề
Set-Login: logged-in
hoặc gọi hàmnavigator.login.setStatus("logged-in")
để thông báo cho trình duyệt rằng người dùng đã đăng nhập. - Gọi
IdentityProvider.close()
để đóng hộp thoại.
![A](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm.gif?authuser=9&hl=vi)
Thông báo cho trình duyệt về trạng thái đăng nhập của người dùng trên nhà cung cấp danh tính
API trạng thái đăng nhập là một cơ chế nơi một trang web, đặc biệt là một IdP, thông báo cho trình duyệt về trạng thái đăng nhập của người dùng trên IdP. Với API này, trình duyệt có thể giảm các yêu cầu không cần thiết đối với IdP và giảm thiểu những cuộc tấn công về thời gian tiềm ẩn.
IdP có thể báo hiệu trạng thái đăng nhập của người dùng cho trình duyệt bằng cách gửi một tiêu đề HTTP
hoặc bằng cách gọi API JavaScript khi người dùng đăng nhập trên IdP hoặc khi
người dùng bị đăng xuất khỏi tất cả tài khoản IdP của họ. Đối với mỗi IdP (được xác định bằng
config) thì trình duyệt sẽ lưu giữ một biến ba trạng thái đại diện cho trạng thái đăng nhập
với các giá trị có thể là logged-in
, logged-out
và unknown
. Trạng thái mặc định
là unknown
.
Để báo hiệu rằng người dùng đã đăng nhập, hãy gửi một tiêu đề HTTP Set-Login: logged-in
trong thành phần điều hướng ở cấp cao nhất hoặc trong một yêu cầu về tài nguyên phụ trên cùng một trang web tại IdP (nhà cung cấp danh tính)
máy chủ gốc:
Set-Login: logged-in
Ngoài ra, hãy gọi API JavaScript navigator.login.setStatus("logged-in")
qua nguồn gốc của IdP (nhà cung cấp danh tính) trong phần điều hướng cấp cao nhất:
navigator.login.setStatus("logged-in")
Các lệnh gọi này ghi lại trạng thái đăng nhập của người dùng là logged-in
. Khi người dùng đăng nhập
trạng thái được đặt thành logged-in
, FedCM gọi bên bị hạn chế sẽ gửi yêu cầu đến nhà cung cấp danh tính
tài khoản người dùng và hiển thị các tài khoản khả dụng cho người dùng trong FedCM
.
Để báo hiệu rằng người dùng đã đăng xuất khỏi tất cả các tài khoản của họ, hãy gửi tiêu đề HTTP Set-Login:
logged-out
trong thanh điều hướng cấp cao nhất hoặc tài nguyên phụ trên cùng một trang web
yêu cầu tại nguồn gốc của IdP:
Set-Login: logged-out
Ngoài ra, hãy gọi API JavaScript navigator.login.setStatus("logged-out")
qua nguồn gốc của IdP (nhà cung cấp danh tính) trong phần điều hướng cấp cao nhất:
navigator.login.setStatus("logged-out")
Các lệnh gọi này ghi lại trạng thái đăng nhập của người dùng là logged-out
. Khi chế độ cài đặt của người dùng
trạng thái đăng nhập là logged-out
, việc gọi FedCM tự động không thành công mà không thực hiện
yêu cầu điểm cuối của tài khoản của IdP.
Trạng thái của unknown
được thiết lập trước khi IdP gửi một tín hiệu thông qua Trạng thái đăng nhập
API. Unknown
được đưa ra để chuyển đổi tốt hơn vì người dùng có thể đã
đã đăng nhập vào IdP khi API này được gửi. IdP có thể không có
cơ hội báo hiệu điều này cho trình duyệt vào thời điểm FedCM được gọi lần đầu tiên. Trong phần này
trong trường hợp khác, Chrome sẽ gửi yêu cầu tới điểm cuối tài khoản của IdP và cập nhật
dựa trên phản hồi từ điểm cuối của tài khoản:
- Nếu điểm cuối trả về danh sách tài khoản đang hoạt động, hãy cập nhật trạng thái thành
logged-in
rồi mở hộp thoại FedCM để xem các tài khoản đó. - Nếu điểm cuối không trả về tài khoản nào, hãy cập nhật trạng thái thành
logged-out
và không thực hiện được lệnh gọi FedCM.
Cho phép người dùng đăng nhập thông qua một luồng đăng nhập động
Mặc dù IdP liên tục thông báo trạng thái đăng nhập của người dùng cho trình duyệt,
có thể không được đồng bộ hoá, chẳng hạn như khi phiên hết hạn. Trình duyệt sẽ cố gắng
gửi một yêu cầu đã được xác thực đến điểm cuối của tài khoản khi trạng thái đăng nhập là
logged-in
, nhưng máy chủ không trả về tài khoản nào vì phiên không còn
sẵn có. Trong trường hợp như vậy, trình duyệt có thể cho phép người dùng đăng nhập một cách linh động
đến IdP thông qua cửa sổ bật lên.
Đăng nhập vào bên đáng tin cậy bằng nhà cung cấp danh tính
Sau khi có cấu hình và điểm cuối của IdP, bên bị hạn chế có thể gọi
navigator.credentials.get()
để yêu cầu cho phép người dùng đăng nhập vào bên bị hạn chế
với IdP.
Trước khi gọi API, bạn cần xác nhận rằng [FedCM có mặt trên trình duyệt của người dùng]. Để kiểm tra xem FedCM có sẵn hay không, hãy bọc mã này quanh Triển khai FedCM:
if ('IdentityCredential' in window) {
// If the feature is available, take action
}
Để yêu cầu cho phép người dùng đăng nhập vào IdP qua bên bị hạn chế, hãy làm như sau: ví dụ:
const credential = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
Thuộc tính providers
lấy một mảng IdentityProvider
các đối tượng có
các thuộc tính sau:
Thuộc tính | Mô tả |
---|---|
configURL (bắt buộc) |
Đường dẫn đầy đủ của tệp cấu hình IdP. |
clientId (bắt buộc) |
Giá trị nhận dạng ứng dụng của RP do IdP (nhà cung cấp danh tính) cấp. |
nonce (không bắt buộc) |
Một chuỗi ngẫu nhiên để đảm bảo phản hồi được đưa ra cho yêu cầu cụ thể này. Ngăn chặn các cuộc tấn công phát lại. |
loginHint (không bắt buộc) |
Bằng cách chỉ định một trong login_hints giá trị được cung cấp bởi
điểm cuối của tài khoản, FedCM
hộp thoại hiển thị chọn lọc tài khoản được chỉ định. |
domainHint (không bắt buộc) |
Bằng cách chỉ định một trong domain_hints giá trị được cung cấp bởi
điểm cuối của tài khoản, FedCM
hộp thoại hiển thị chọn lọc tài khoản được chỉ định. |
Trình duyệt xử lý các trường hợp sử dụng đăng ký và đăng nhập khác nhau tuỳ thuộc vào
sự tồn tại của approved_clients
trong phản hồi từ danh sách tài khoản
điểm cuối. Trình duyệt sẽ không hiển thị thông tin công bố
văn bản "Để tiếp tục với ...." nếu người dùng đã đăng ký bên bị hạn chế.
Trạng thái đăng ký được xác định dựa trên việc các điều kiện sau đây đã thực hiện hay chưa:
- Nếu
approved_clients
bao gồmclientId
của RP. - Nếu trình duyệt ghi nhớ rằng người dùng đã đăng ký bên bị hạn chế.
Khi RP gọi navigator.credentials.get()
, các hoạt động sau đây sẽ diễn ra
địa điểm:
- Trình duyệt gửi yêu cầu và tìm nạp nhiều tài liệu:
- Tệp phổ biến và cấu hình IdP (nhà cung cấp danh tính) khai báo điểm cuối.
- Danh sách tài khoản.
- Không bắt buộc: URL về chính sách quyền riêng tư và điều khoản dịch vụ của bên bị hạn chế, truy xuất từ điểm cuối siêu dữ liệu của ứng dụng.
- Trình duyệt sẽ hiển thị danh sách các tài khoản mà người dùng có thể sử dụng để đăng nhập, cũng như các điều khoản dịch vụ và chính sách bảo mật (nếu có).
- Sau khi người dùng chọn một tài khoản để đăng nhập, hãy gửi một yêu cầu đến mã nhận dạng điểm cuối của câu nhận định được gửi đến IdP để truy xuất một mã thông báo.
- RP có thể xác thực mã thông báo để xác thực người dùng.
![lệnh gọi API đăng nhập](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/login-api-call-a55fdb8f753e8.png?authuser=9&hl=vi)
RP được dự kiến sẽ hỗ trợ các trình duyệt không hỗ trợ FedCM, do đó người dùng có thể sử dụng quy trình đăng nhập hiện có, không phải FedCM. Cho đến cookie của bên thứ ba bị loại bỏ hoàn toàn, tình trạng này vẫn sẽ tồn tại không vấn đề gì.
Sau khi máy chủ RP xác thực mã thông báo, RP đó có thể đăng ký người dùng hoặc cho phép họ đăng nhập và bắt đầu một phiên mới.
API Gợi ý đăng nhập
Sau khi người dùng đăng nhập, đôi khi bên phụ thuộc (RP) yêu cầu người dùng xác thực lại. Tuy nhiên, người dùng có thể không chắc chắn họ đang sử dụng tài khoản nào. Nếu bên bị hạn chế có thể chỉ định xem nên đăng nhập bằng tài khoản nào thì sẽ dễ dàng hơn cho người dùng chọn một tài khoản.
Các bên bị hạn chế có thể hiển thị có chọn lọc một tài khoản cụ thể bằng cách gọi
navigator.credentials.get()
với thuộc tính loginHint
có một trong
Các giá trị login_hints
được tìm nạp từ danh sách tài khoản
điểm cuối, như minh hoạ trong mã mẫu sau đây:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/manifest.json",
clientId: "123",
nonce: nonce,
loginHint : "demo1@example.com"
}]
}
});
Khi không có tài khoản nào khớp với loginHint
, hộp thoại FedCM sẽ hiển thị lời nhắc đăng nhập,
cho phép người dùng đăng nhập vào một tài khoản IdP khớp với gợi ý mà
bên bị hạn chế. Khi người dùng nhấn vào lời nhắc, một cửa sổ bật lên sẽ mở ra cùng với
URL đăng nhập được chỉ định trong tệp cấu hình. Sau đó, đường liên kết này sẽ là
được thêm cùng với gợi ý đăng nhập và tham số truy vấn gợi ý miền.
API Gợi ý tên miền
Có những trường hợp mà bên bị hạn chế đã biết rằng chỉ những tài khoản liên kết với một số miền nhất định được phép đăng nhập vào trang web. Điều này đặc biệt phổ biến ở doanh nghiệp khi trang web được truy cập bị hạn chế ở miền. Nhằm mang lại trải nghiệm tốt hơn cho người dùng, FedCM API chỉ cho phép RP hiện những tài khoản có thể dùng để đăng nhập vào RP đó. Việc này giúp ngăn chặn các tình huống nơi người dùng cố gắng đăng nhập vào RP bằng tài khoản bên ngoài công ty miền, chỉ nhận được thông báo lỗi sau đó (hoặc tắt tiếng khi đăng nhập không hoạt động) vì không sử dụng đúng loại tài khoản.
Các bên bị hạn chế có thể chỉ hiển thị có chọn lọc các tài khoản trùng khớp bằng cách gọi
navigator.credentials.get()
với thuộc tính domainHint
có một trong
Các giá trị domain_hints
được tìm nạp từ danh sách tài khoản
điểm cuối, như minh hoạ trong mã mẫu sau đây:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/manifest.json",
clientId: "abc",
nonce: nonce,
domainHint : "corp.example"
}]
}
});
Khi không có tài khoản nào khớp với domainHint
, hộp thoại FedCM sẽ hiển thị lời nhắc đăng nhập,
cho phép người dùng đăng nhập vào một tài khoản IdP khớp với gợi ý mà
bên bị hạn chế. Khi người dùng nhấn vào lời nhắc, một cửa sổ bật lên sẽ mở ra cùng với
URL đăng nhập được chỉ định trong tệp cấu hình. Sau đó, đường liên kết này sẽ là
được thêm cùng với gợi ý đăng nhập và tham số truy vấn gợi ý miền.
![Ví dụ về lời nhắc đăng nhập khi không có tài khoản nào khớp với domainHint.](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-123.jpg?authuser=9&hl=vi)
domainHint
.Hiện thông báo lỗi
Đôi khi, IdP có thể không cấp được mã thông báo vì những lý do chính đáng, chẳng hạn như giống như khi máy khách không được phép, thì máy chủ tạm thời không khả dụng. Nếu IdP trả về một "lỗi" RP có thể phát hiện được nội dung đó, cũng như Chrome thông báo cho người dùng bằng cách hiển thị giao diện người dùng của trình duyệt với thông tin lỗi được cung cấp bởi IdP (nhà cung cấp danh tính).
![A](https://developers-dot-devsite-v2-prod.appspot.com/static/privacy-sandbox/assets/images/blog/fedcm-120-4.png?authuser=9&hl=vi)
try {
const cred = await navigator.credentials.get({
identity: {
providers: [
{
configURL: "https://idp.example/manifest.json",
clientId: "1234",
},
],
}
});
} catch (e) {
const code = e.code;
const url = e.url;
}
Tự động xác thực lại người dùng sau lần xác thực ban đầu
Tự động xác thực lại FedCM ("tự động xác thực lại" có thể cho phép người dùng tự động xác thực lại khi họ sẽ quay lại sau lần xác thực ban đầu bằng FedCM. Tên viết tắt xác thực" ở đây có nghĩa là người dùng tạo một tài khoản hoặc đăng nhập vào trang web bằng cách nhấn vào nút "Continue as..." (Tiếp tục bằng...) trên hộp thoại đăng nhập của FedCM lần đầu tiên trên cùng một phiên bản trình duyệt.
Mặc dù trải nghiệm người dùng rõ ràng là có ý nghĩa trước khi người dùng tạo tài khoản liên kết để ngăn chặn việc theo dõi (một trong những mục tiêu chính của FedCM), nó cồng kềnh không cần thiết sau khi người dùng đã trải qua một lần: sau khi người dùng cấp quyền cho phép giao tiếp giữa RP và IdP, không có lợi ích về quyền riêng tư hoặc bảo mật khi thực thi một người dùng phản cảm khác xác nhận cho một điều gì đó mà họ đã xác nhận trước đó.
Với tính năng tự động xác thực lại, trình duyệt sẽ thay đổi hành vi của mình tùy thuộc vào tùy chọn bạn
chỉ định cho mediation
khi gọi navigator.credentials.get()
.
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/fedcm.json",
clientId: "1234",
}],
},
mediation: 'optional', // this is the default
});
// `isAutoSelected` is `true` if auto-reauthn was performed.
const isAutoSelected = cred.isAutoSelected;
mediation
là một thuộc tính trong phần Quản lý thông tin xác thực
API,
ứng dụng sẽ hoạt động giống nhau
đường đi
như đối với
PasswordCredential
và
FederatedCredential
và được hỗ trợ một phần bởi
PublicKeyCredential
của Google. Thuộc tính này chấp nhận 4 giá trị sau:
'optional'
(mặc định): Tự động xác thực lại nếu có thể, yêu cầu dàn xếp nếu không. T4 khuyên bạn chọn tuỳ chọn này trên trang đăng nhập.'required'
: Luôn yêu cầu dàn xếp để tiếp tục, ví dụ: nhấp vào "Tiếp tục" trên giao diện người dùng. Chọn tùy chọn này nếu người dùng của bạn muốn cấp quyền một cách rõ ràng mỗi khi cần xác thực.'silent'
: Tự động xác thực lại nếu có thể, tự động không thành công mà không yêu cầu dàn xếp nếu không. Bạn nên chọn tuỳ chọn này trên các trang ngoại trừ trang đăng nhập chuyên biệt mà là nơi bạn muốn duy trì trạng thái đăng nhập của người dùng—cho ví dụ: trang mặt hàng trên trang web vận chuyển hoặc trang bài viết trên một trang tin tức của bạn.'conditional'
: Đang dùng cho WebAuthn và hiện chưa có cho FedCM.
Với lệnh gọi này, tính năng tự động xác thực lại sẽ diễn ra trong các điều kiện sau:
- Bạn có thể dùng FedCM. Ví dụ: người dùng chưa vô hiệu hoá FedCM trên toàn cầu hoặc cho bên bị hạn chế trong phần cài đặt.
- Người dùng chỉ sử dụng một tài khoản có API FedCM để đăng nhập vào trang web trên trình duyệt.
- Người dùng được đăng nhập vào IdP bằng tài khoản đó.
- Quá trình tự động xác thực lại đã không xảy ra trong vòng 10 phút vừa qua.
- Bên bị hạn chế chưa gọi
Sau đó là
navigator.credentials.preventSilentAccess()
lần đăng nhập trước đó.
Khi những điều kiện này được đáp ứng, hệ thống sẽ tìm cách tự động xác thực lại
người dùng bắt đầu ngay khi FedCM navigator.credentials.get()
được gọi.
Khi mediation: optional
, tính năng tự động xác thực lại có thể
không có vì những nguyên nhân
chỉ trình duyệt biết; bên bị hạn chế có thể kiểm tra xem tự động xác thực lại có được thực hiện bằng
kiểm tra thuộc tính isAutoSelected
.
Điều này rất hữu ích để đánh giá hiệu suất của API và cải thiện trải nghiệm người dùng cho phù hợp.
Ngoài ra, khi tính năng này không dùng được, người dùng có thể được nhắc đăng nhập bằng
dàn xếp người dùng, đây là một quy trình với mediation: required
.
Thực thi tính năng dàn xếp bằng preventSilentAccess()
Việc tự động xác thực lại người dùng ngay sau khi họ đăng xuất sẽ không tạo ra
trải nghiệm người dùng rất tốt. Đó là lý do FedCM có khoảng thời gian yên tĩnh 10 phút sau khi
tự động xác thực lại để ngăn chặn hành vi này. Điều này có nghĩa là quá trình tự động xác thực lại sẽ diễn ra
tối đa một lần trong mỗi 10 phút trừ phi người dùng đăng nhập lại trong vòng
10 phút. RP phải gọi navigator.credentials.preventSilentAccess()
để
yêu cầu trình duyệt tắt tính năng tự động xác thực lại khi người dùng đăng xuất
bên bị hạn chế, ví dụ: bằng cách nhấp vào nút đăng xuất.
function signout() {
navigator.credentials.preventSilentAccess();
location.href = '/signout';
}
Người dùng có thể chọn không tự động xác thực lại trong phần cài đặt
Người dùng có thể chọn không sử dụng tính năng tự động xác thực lại trên trình đơn cài đặt:
- Trên Chrome dành cho máy tính, hãy truy cập
chrome://password-manager/settings
> Đăng nhập tự động. - Trên Android Chrome, hãy mở Cài đặt > Trình quản lý mật khẩu > Nhấn vào bánh răng ở góc trên cùng bên phải > Tự động đăng nhập.
Khi tắt nút bật/tắt, người dùng có thể chọn không sử dụng tính năng tự động xác thực lại tất cả khi kết hợp cùng nhau. Chế độ cài đặt này được lưu trữ và đồng bộ hoá trên các thiết bị, nếu người dùng đã đăng nhập vào Tài khoản Google trên phiên bản Chrome và quá trình đồng bộ hoá bật.
Ngắt kết nối IdP khỏi RP
Nếu trước đó, một người dùng đã đăng nhập vào bên bị hạn chế bằng IdP (nhà cung cấp danh tính) thông qua FedCM,
mối quan hệ được trình duyệt ghi nhớ cục bộ dưới dạng danh sách
tài khoản. RP có thể bắt đầu ngắt kết nối bằng cách gọi lệnh
Hàm IdentityCredential.disconnect()
. Hàm này có thể được gọi từ một
khung RP cấp cao nhất. RP cần truyền configURL
, clientId
mà nó sử dụng
trong IdP (nhà cung cấp danh tính) và một accountHint
để ngắt kết nối với IdP. Tài khoản
gợi ý có thể là một chuỗi tuỳ ý, miễn là điểm cuối ngắt kết nối có thể xác định
tài khoản, ví dụ: địa chỉ email hoặc mã nhận dạng người dùng mà không nhất thiết
khớp với mã tài khoản mà điểm cuối của danh sách tài khoản đã cung cấp:
// Disconnect an IdP account "account456" from the RP "https://idp.com/". This is invoked on the RP domain.
IdentityCredential.disconnect({
configURL: "https://idp.com/config.json",
clientId: "rp123",
accountHint: "account456"
});
IdentityCredential.disconnect()
trả về Promise
. Lời hứa này có thể mang đến
ngoại lệ vì những lý do sau:
- Người dùng chưa đăng nhập vào bên bị hạn chế bằng IdP (nhà cung cấp danh tính) qua FedCM.
- API được gọi từ bên trong iframe mà không có chính sách về quyền FedCM.
- configURL không hợp lệ hoặc thiếu điểm cuối ngắt kết nối.
- Không kiểm tra được Chính sách bảo mật nội dung (CSP).
- Có một yêu cầu ngắt kết nối đang chờ xử lý.
- Người dùng đã tắt FedCM trong phần cài đặt của trình duyệt.
Khi điểm cuối ngắt kết nối của IdP trả về một thì RP và IdP sẽ bị ngắt kết nối trên của bạn và lời hứa sẽ được giải quyết. Mã của các tài khoản đã ngắt kết nối là được chỉ định trong phản hồi từ ngắt kết nối điểm cuối.
Gọi FedCM từ trong iframe trên nhiều nguồn gốc
Bạn có thể gọi FedCM từ bên trong iframe trên nhiều nguồn gốc bằng cách sử dụng
identity-credentials-get
chính sách quyền, nếu khung gốc cho phép. Người nhận
do đó, hãy thêm thuộc tính allow="identity-credentials-get"
vào thẻ iframe
như sau:
<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>
Bạn có thể xem ví dụ thực tế về tính năng này trong ví dụ.
Theo tuỳ chọn, nếu khung gốc muốn hạn chế nguồn gốc để gọi FedCM,
gửi tiêu đề Permissions-Policy
kèm theo danh sách các nguồn được phép.
Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")
Bạn có thể tìm hiểu thêm về cách hoạt động của Chính sách về quyền tại bài viết Kiểm soát các tính năng của trình duyệt có Quyền truy cập Chính sách.