Federated Credential Management API 开发者指南

了解如何使用 FedCM 实现可保护隐私的身份联合。

FedCM(联邦身份凭据管理)是一种可保护隐私的联邦身份服务(例如“使用...账号登录”)方法,用户无需与身份服务或网站分享个人信息即可登录网站。

如需详细了解 FedCM 使用场景、用户体验流程和 API 路线图,请参阅 FedCM API 简介

FedCM 开发环境

您需要在 Chrome 中的 IdP 和 RP 上都设置安全上下文(HTTPS 或 localhost),才能使用 FedCM。

在 Android 设备上的 Chrome 中调试代码

在本地设置并运行服务器,以调试 FedCM 代码。您可以在使用 USB 线连接且支持端口转发的 Android 设备上,在 Chrome 中访问此服务器

您可以按照远程调试 Android 设备中的说明,使用桌面版开发者工具调试 Android 设备上的 Chrome。

在 Chrome 中阻止第三方 Cookie

通过将 Chrome 配置为屏蔽第三方 Cookie,模拟第三方 Cookie 逐步淘汰
通过将 Chrome 配置为阻止第三方 Cookie 来模拟第三方 Cookie 逐步淘汰

在实际强制执行 FedCM 之前,您可以在 Chrome 上测试 FedCM 在没有第三方 Cookie 的情况下如何运作。

如需屏蔽第三方 Cookie,请使用无痕模式,或在桌面设备的设置中选择 chrome://settings/cookies 下的“屏蔽第三方 Cookie”,或在移动设备上依次选择设置 > 网站设置 > Cookie

使用 FedCM API

如需与 FedCM 集成,您可以为账号列表创建已知文件配置文件和端点断言发出,还可以选择创建客户端元数据

然后,FedCM 会公开 JavaScript API,供 RP 使用这些 API 与 IdP 进行登录

创建 well-known 文件

为防止跟踪器滥用 API,必须从 IdP 的 eTLD+1/.well-known/web-identity 中提供 well-known 文件。

例如,如果 IdP 端点在 https://accounts.idp.example/ 下提供,则必须在 https://idp.example/.well-known/web-identity 下提供 well-known 文件以及 IdP 配置文件。下面是一个众所周知的文件内容示例:

{
  "provider_urls": ["https://accounts.idp.example/config.json"]
}

JSON 文件必须包含 provider_urls 属性,其中包含一个 IdP 配置文件网址数组,该数组可由 RP 指定为 navigator.credentials.getconfigURL 的路径部分。数组中的网址字符串数量不得超过 1 个,但将来可能会根据您的反馈而有所变化。

创建 IdP 配置文件和端点

IdP 配置文件为浏览器提供了必需端点的列表。IdP 将托管此配置文件以及所需的端点和网址。所有 JSON 响应都必须使用 application/json 内容类型提供。

配置文件的网址由向 RP 上执行的 navigator.credentials.get 调用提供的值决定

const credential = await navigator.credentials.get({
  identity: {
    context: 'signup',
    providers: [{
      configURL: 'https://accounts.idp.example/config.json',
      clientId: '********',
      nonce: '******'
    }]
  }
});
const { token } = credential;

将 IdP 配置文件位置的完整网址指定为 configURL。在 RP 上调用 navigator.credentials.get() 时,浏览器会使用不含 Origin 标头或 Referer 标头的 GET 请求提取配置文件。请求不含 Cookie,也不遵循重定向。 这样做可有效防止 IdP 了解是谁发出了请求以及哪个 RP 正在尝试建立连接。例如:

GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity

浏览器希望从 IdP 收到 JSON 响应,其中包含以下属性:

属性 说明
accounts_endpoint(必需) accounts 端点的网址。
client_metadata_endpoint(可选) 客户端元数据端点的网址。
id_assertion_endpoint(必需) ID 断言端点的网址。
disconnect(可选) 断开连接端点的网址。
login_url(必需) 用户登录 IdP 的登录页网址
branding(可选) 包含各种品牌选项的对象。
branding.background_color(可选) 用于设置“继续以...身份操作”按钮背景颜色的品牌化选项。使用相关的 CSS 语法,即 hex-colorhsl()rgb()named-color
branding.color(可选) 用于设置“继续以...身份操作”按钮文本颜色的品牌选项。使用相关的 CSS 语法,即 hex-colorhsl()rgb()named-color
branding.icons(可选) 用于设置登录对话框中显示的图标对象的品牌化选项。图标对象是一个包含两个参数的数组:
  • url(必需):图标图片的网址。它不支持 SVG 图片。
  • size(可选):应用假定为方形且分辨率单一的图标尺寸。此数字必须大于或等于 25。

RP 可以通过 navigator.credentials.get()identity.context 值修改 FedCM 对话框界面中的字符串,以适应预定义的身份验证上下文。可选属性可以是 "signin"(默认)、"signup""use""continue" 之一。

如何将品牌信息应用于 FedCM 对话框
如何将品牌信息应用于 FedCM 对话框

以下是身份提供程序的响应正文示例:

{
  "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
    }]
  }
}

浏览器提取配置文件后,会向 IdP 端点发送后续请求:

IdP 端点
IdP 端点

账号端点

IdP 的账号端点会返回用户当前在 IdP 上登录的账号列表。如果 IdP 支持多个账号,此端点将返回所有已登录的账号。

浏览器发送包含 Cookie 的 GET 请求,其中包含 SameSite=None,但不包含 client_id 参数、Origin 标头或 Referer 标头。这样可以有效地防止 IdP 了解用户正在尝试登录的 RP。例如:

GET /accounts.php HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

收到请求后,服务器应执行以下操作:

  1. 验证请求是否包含 Sec-Fetch-Dest: webidentity HTTP 标头。
  2. 将会话 Cookie 与已登录账号的 ID 进行匹配。
  3. 响应并提供账号列表。

浏览器预期 JSON 响应包含一个 accounts 属性,其中包含具有以下属性的账号信息数组:

属性 说明
id(必需) 用户的唯一 ID。
name(必需) 用户的名字和姓氏。
email(必需) 用户的电子邮件地址。
given_name(可选) 用户的名字。
picture(可选) 用户头像图片的网址。
approved_clients(可选) 用户已注册的 RP 客户端 ID 的数组。
login_hints(可选) 一个数组,包含 IdP 支持指定账号的所有可能的过滤条件类型。RP 可以通过 loginHint 属性调用 navigator.credentials.get(),以选择性地显示指定的账号。
domain_hints(可选) 账号关联的所有网域的数组。RP 可以使用 domainHint 属性调用 navigator.credentials.get() 来过滤账号。

响应正文示例:

{
  "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"]
  }]
}

如果用户未登录,请返回 HTTP 401(未经授权)。

返回的账号列表将由浏览器使用,RP 无法使用。

客户端元数据端点

IdP 的客户端元数据端点会返回信赖方的元数据,例如 RP 的隐私权政策和服务条款。RP 应提前向 IdP 提供指向其隐私权政策和服务条款的链接。如果用户尚未在 RP 上使用 IdP 注册,系统会在登录对话框中显示这些链接。

浏览器使用不带 Cookie 的 client_id navigator.credentials.get 发送 GET 请求。例如:

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

收到请求后,服务器应执行以下操作:

  1. 确定 client_id 的 RP。
  2. 使用客户端元数据进行响应。

客户端元数据端点的属性包括:

属性 说明
privacy_policy_url(可选) RP 隐私权政策网址。
terms_of_service_url(可选) RP 服务条款网址。

浏览器会要求从该端点返回 JSON 响应:

{
  "privacy_policy_url": "https://rp.example/privacy_policy.html",
  "terms_of_service_url": "https://rp.example/terms_of_service.html",
}

返回的客户端元数据会被浏览器使用,并且不可用于 RP。

ID 断言端点

IdP 的 ID 断言端点会为其已登录的用户返回断言。当用户使用 navigator.credentials.get() 调用登录 RP 网站时,浏览器会向此端点发送包含 SameSite=None 的 Cookie 和内容类型为 application/x-www-form-urlencodedPOST 请求,其中包含以下信息:

属性 说明
client_id(必需) RP 的客户端标识符。
account_id(必需) 登录用户的唯一 ID。
nonce(可选) 请求 Nonce,由 RP 提供。
disclosure_text_shown 返回 "true""false" 字符串(而不是布尔值)。如果未显示披露文本,则结果为 "false"。如果 RP 的客户 ID 包含在 accounts 端点响应的 approved_clients 属性列表中,或者浏览器在过去观察到注册时刻时未检测到 approved_clients,就会出现这种情况。
is_auto_selected 如果对 RP 执行了自动重新身份验证,则 is_auto_selected 表示 "true"。否则为 "false"。这有助于支持更多与安全相关的功能。例如,某些用户可能更喜欢更高的安全级别,这要求在身份验证中采用显式用户中介。如果 IdP 收到的令牌请求没有使用此类中介,则可能会以其他方式处理该请求。例如,返回一个错误代码,以便 RP 可以使用 mediation: required 再次调用 FedCM API。

HTTP 标头示例:

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

收到请求后,服务器应执行以下操作:

  1. 使用 CORS(跨源资源共享)响应请求。
  2. 验证请求是否包含 Sec-Fetch-Dest: webidentity HTTP 标头。
  3. Origin 标头与由 client_id 确定的 RP 来源进行匹配。如果不匹配,请拒绝。
  4. account_id 与已登录账号的 ID 进行匹配。如果不匹配,则拒绝。
  5. 使用令牌进行响应。如果请求被拒绝,请返回错误响应

令牌的签发方式取决于 IdP,但通常,令牌使用账号 ID、客户端 ID、签发者来源 nonce 等信息进行签名,以便 RP 验证令牌的真实性。

浏览器希望 JSON 响应包含以下属性:

属性 说明
token(必需) 令牌是包含与身份验证相关的声明的字符串。
{
  "token": "***********"
}

浏览器将返回的令牌传递给 RP,以便 RP 可以验证身份验证。

返回错误响应

id_assertion_endpoint 还可以返回“错误”响应,其中包含两个可选字段:

  • code:IdP 可以从 OAuth 2.0 指定的错误列表中选择一个已知错误(invalid_requestunauthorized_clientaccess_deniedserver_errortemporarily_unavailable),也可以使用任何任意字符串。如果是后者,Chrome 会使用通用错误消息呈现错误界面,并将代码传递给 RP。
  • url:用于标识包含错误相关信息的人类可读网页,以向用户提供有关错误的更多信息。此字段对用户很有用,因为浏览器无法在原生界面中提供丰富的错误消息。例如,后续步骤的链接、客户服务联系信息等。如果用户想要详细了解错误详情和修正方法,可以通过浏览器界面访问所提供的页面了解详情。该网址必须与 IdP configURL 位于同一网站。
// id_assertion_endpoint response
{
  "error" : {
     "code": "access_denied",
     "url" : "https://idp.example/error?type=access_denied"
  }
}

断开端点

通过调用 IdentityCredential.disconnect(),浏览器会向此断开连接端点发送包含 SameSite=None 和内容类型为 application/x-www-form-urlencoded 的跨源 POST 请求,其中包含以下信息:

属性 说明
account_hint IdP 账号的提示。
client_id RP 的客户端标识符。
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

收到请求后,服务器应执行以下操作:

  1. 使用 CORS(跨源资源共享)响应请求。
  2. 验证请求是否包含 Sec-Fetch-Dest: webidentity HTTP 标头。
  3. Origin 标头与由 client_id 确定的 RP 源进行匹配。如果不匹配,请拒绝。
  4. account_hint 与已登录账号的 ID 进行匹配。
  5. 解除用户账号与 RP 的关联。
  6. 以 JSON 格式向浏览器响应已识别的用户账号信息。

响应 JSON 载荷示例如下:

{
  "account_id": "account456"
}

相反,如果 IdP 希望浏览器解除与 RP 关联的所有账号,请传递与任何账号 ID 都不匹配的字符串,例如 "*"

登录网址

使用 Login Status API 时,IdP 必须向浏览器告知用户的登录状态。不过,状态可能会不同步,例如在会话过期时。在这种情况下,浏览器可以通过使用 idp 配置文件login_url 指定的登录页面网址,动态让用户登录 IdP。

FedCM 对话框会显示一条提示登录的消息,如下图所示。

A
建议登录 IdP 的 FedCM 对话框。

当用户点击 Continue 按钮时,浏览器会为 IdP 的登录页面打开一个弹出式窗口。

FedCM 对话框示例。
点击“登录 IdP”按钮后显示的示例对话框。

该对话框是一个包含第一方 Cookie 的常规浏览器窗口。对话框中发生的任何情况都取决于 IdP,并且没有窗口句柄可用于向 RP 页面发出跨源通信请求。用户登录后,IdP 应执行以下操作:

  • 发送 Set-Login: logged-in 标头或调用 navigator.login.setStatus("logged-in") API 以告知浏览器用户已登录。
  • 调用 IdentityProvider.close() 以关闭对话框。
用户使用 FedCM 登录 IdP 后,再登录 RP。

告知浏览器用户在身份提供程序中的登录状态

Login Status API 是一种机制,在该机制中,网站(尤其是 IdP)会将用户在 IdP 上的登录状态告知浏览器。借助此 API,浏览器可以减少对 IDP 的不必要请求,并缓解潜在的时间攻击。

当用户在 IdP 上登录或退出所有 IdP 账号时,IdP 可以通过发送 HTTP 标头或调用 JavaScript API 向浏览器发送用户的登录状态信号。对于每个 IdP(通过其配置网址进行标识),浏览器都会保留一个三态变量来表示登录状态,可能的值为 logged-inlogged-outunknown。默认状态为 unknown

如需指示用户已登录,请在顶级导航中发送 Set-Login: logged-in HTTP 标头,或在 IdP 源中发送同一网站子资源请求:

Set-Login: logged-in

或者,您也可以在顶级导航栏中的 IdP 来源中调用 JavaScript API navigator.login.setStatus("logged-in")

navigator.login.setStatus("logged-in")

这些调用会将用户的登录状态记录为 logged-in。当用户的登录状态设置为 logged-in 时,调用 FedCM 的 RP 会向 IdP 的账号端点发出请求,并在 FedCM 对话框中向用户显示可用账号。

如需指示用户已退出所有账号,请在顶级导航中发送 Set-Login: logged-out HTTP 标头,或在 IdP 源中发送同一网站子资源请求:

Set-Login: logged-out

或者,在顶级导航中,从 IdP 源调用 JavaScript API navigator.login.setStatus("logged-out")

navigator.login.setStatus("logged-out")

这些调用会将用户的登录状态记录为 logged-out。当用户的登录状态为 logged-out 时,调用 FedCM 会静默失败,而不会向 IdP 的账号端点发出请求。

在 IdP 使用 Login Status API 发送信号之前,系统会设置 unknown 状态。我们引入了 Unknown 来实现更好的转换效果,因为在此 API 交付时,用户可能已经登录 IdP。在首次调用 FedCM 时,IdP 可能没有机会向浏览器发出此信号。在这种情况下,Chrome 会向 IdP 的账号端点发出请求,并根据账号端点的响应更新状态:

  • 如果端点返回活跃账号的列表,请将状态更新为 logged-in 并打开 FedCM 对话框以显示这些账号。
  • 如果端点未返回任何账号,请将状态更新为 logged-out 并使 FedCM 调用失败。

让用户通过动态登录流程登录

即使 IdP 会持续向浏览器告知用户的登录状态,但状态也可能会不同步,例如在会话过期时。当登录状态为 logged-in 时,浏览器会尝试向账号端点发送一个经过凭据验证的请求,但服务器未返回任何账号,因为该会话不再可用。在这种情况下,浏览器可以动态地允许用户通过弹出式窗口登录 IdP

使用身份提供方登录信赖方

IdP 的配置和端点可用后,RP 可以调用 navigator.credentials.get() 来请求允许用户通过 IdP 登录 RP。

在调用该 API 之前,您需要确认 [FedCM 在用户的浏览器上可用]。如需检查 FedCM 是否可用,请将此代码封装在 FedCM 实现中:

if ('IdentityCredential' in window) {
  // If the feature is available, take action
}

如需请求允许用户从 RP 登录 IdP,请执行以下操作,例如:

const credential = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://accounts.idp.example/config.json',
      clientId: '********',
      nonce: '******'
    }]
  }
});
const { token } = credential;

providers 属性接受一个具有以下属性的 IdentityProvider 对象数组:

属性 说明
configURL(必需) IdP 配置文件的完整路径。
clientId(必需) IdP 签发的 RP 客户端标识符。
nonce(可选) 一个随机字符串,确保针对此特定请求发出响应。防范重放攻击。
loginHint(可选) 通过指定 accounts 端点提供的 login_hints 值之一,FedCM 对话框会选择性地显示指定的账号。
domainHint(可选) 通过指定账号端点提供的 domain_hints 值之一,FedCM 对话框会选择性地显示指定的账号。

浏览器会根据 accounts list 端点响应中是否存在 approved_clients 来不同地处理注册和登录用例。如果用户已注册 RP,浏览器将不会显示披露文本“To continue with ....”(如要继续...)

注册状态取决于是否满足以下条件:

  • 如果 approved_clients 包含 RP 的 clientId
  • 如果浏览器记得用户已注册 RP。
用户通过 FedCM 登录 RP。

当 RP 调用 navigator.credentials.get() 时,会发生以下 activity:

  1. 浏览器发送请求并提取多个文档:
    1. 众所周知的文件和用于声明端点的 IdP 配置文件
    2. 账号列表
    3. 可选:从客户端元数据端点检索到的 RP 隐私权政策和服务条款的网址。
  2. 浏览器会显示用户可以用于登录的账号列表,以及服务条款和隐私权政策(如果有)。
  3. 用户选择用于登录的账号后,系统会将对 ID 断言端点的请求发送到 IdP,以检索令牌。
  4. RP 可以验证令牌以对用户进行身份验证。
登录 API 调用
login API 调用

RP 应支持不支持 FedCM 的浏览器,因此用户应能够使用现有的非 FedCM 登录流程。在第三方 Cookie 完全淘汰之前,这应该不会造成问题。

令牌由 RP 服务器验证后,RP 可以注册用户,也可以让用户登录并开始新的会话。

Login Hint API

用户登录后,有时信赖方 (RP) 会要求用户重新进行身份验证。但用户可能不确定自己使用的是哪个账号。如果 RP 可以指定要使用哪个账号登录,用户便可以更轻松地选择账号。

RP 可以通过将 loginHint 属性与从账号列表端点提取的 login_hints 值之一一起调用 navigator.credentials.get(),以选择性地显示特定账号,如以下代码示例所示:

return await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "123",
      nonce: nonce,
      loginHint : "demo1@example.com"
    }]
  }
});

如果没有账号与 loginHint 匹配,FedCM 对话框会显示登录提示,以便用户登录与 RP 请求的提示相符的 IdP 账号。当用户点按提示时,系统会打开一个弹出式窗口,其中包含配置文件中指定的登录网址。然后,该链接会附加登录提示和网域提示查询参数。

Domain Hint API

在某些情况下,RP 已知晓只有与特定网域关联的账号才能登录该网站。在企业场景中,这种情况尤其常见,因为在这种场景中,被访问的网站仅限于公司网域。为了提供更好的用户体验,FedCM API 允许 RP 仅显示可用于登录 RP 的账号。这样可以防止出现以下情况:用户尝试使用公司网域之外的账号登录 RP,但由于未使用正确类型的账号,系统稍后会显示错误消息(或在登录失败时保持沉默)。

RP 可以通过将 domainHint 属性与从账号列表端点提取的 domain_hints 值之一一起调用 navigator.credentials.get(),从而选择性地仅显示匹配的账号,如以下代码示例所示:

return await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "abc",
      nonce: nonce,
      domainHint : "corp.example"
    }]
  }
});

如果没有账号与 domainHint 匹配,FedCM 对话框会显示登录提示,以便用户登录与 RP 请求的提示相符的 IdP 账号。当用户点按提示时,系统会打开一个弹出式窗口,其中包含配置文件中指定的登录网址。然后,在链接后附加登录提示和网域提示查询参数。

当没有账号与 domainHint 匹配时显示的登录提示示例。
当没有账号与 domainHint 匹配时显示的登录提示示例。

显示错误消息

有时,身份提供方可能出于合法原因而无法签发令牌,例如客户端未经授权、服务器暂时不可用。如果 IdP 返回“错误”响应,RP 可以捕获该响应,Chrome 也会通过显示包含 IdP 提供的错误信息的浏览器界面来通知用户。

A
显示用户登录尝试失败后错误消息的 FedCM 对话框。此字符串与错误类型相关联。
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;
}

在初始身份验证后自动重新验证用户身份

FedCM 自动重新身份验证(简称“auto-reauthn”)可让用户在使用 FedCM 进行初始身份验证后再次访问时自动重新进行身份验证。这里的“初始身份验证”是指用户在同一浏览器实例中首次点按 FedCM 登录对话框中的“Continue as...” 按钮,创建账号或登录 RP 的网站。

虽然在用户创建联合账号以防止跟踪(这是 FedCM 的主要目标之一)之前,明确的用户体验很有意义,但在用户完成一次体验后,再次执行此体验会不必要地繁琐:在用户授予允许 RP 与 IdP 之间通信的权限后,再强制用户针对他们之前已确认的内容再次明确确认,对隐私或安全没有任何好处。

使用自动重新授权时,浏览器会根据您在调用 navigator.credentials.get() 时为 mediation 指定的选项来更改其行为。

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;

mediationCredential Management API 中的属性,其行为与 PasswordCredentialFederatedCredential 相同,并且 PublicKeyCredential 也对其提供部分支持。该属性接受以下四个值:

  • 'optional'(默认):如果可能自动重新验证,则需要中介。我们建议您在登录页面上选择此选项。
  • 'required':始终需要中介才能继续,例如点击界面上的“继续”按钮。如果您希望用户每次需要进行身份验证时都明确授予权限,请选择此选项。
  • 'silent':如果可能,自动重新授权;如果不可能,则静默失败,无需中介。我们建议在专用登录页面以外的页面(例如,物流网站上的商品页面或新闻网站上的文章页面)上选择此选项。
  • 'conditional':用于 WebAuthn,目前不适用于 FedCM。

此调用会在以下情况下自动重新验证:

  • FedCM 可供使用。例如,用户尚未在整个平台中停用 FedCM,或未在设置中为 RP 停用 FedCM。
  • 在此浏览器中,用户仅使用了一个具有 FedCM API 的账号登录网站。
  • 用户已使用该账号登录 IdP。
  • 过去 10 分钟内未发生自动重新验证。
  • RP 在上次登录后未调用 navigator.credentials.preventSilentAccess()

满足这些条件后,系统会在调用 FedCM navigator.credentials.get() 后立即开始自动对用户重新进行身份验证。

mediation: optional 时,由于只有浏览器知道的原因,自动重新授权可能不可用;RP 可以通过检查 isAutoSelected 属性来检查是否执行了自动重新授权。

这有助于评估 API 性能并相应地改善用户体验。 此外,在 API 不可用时,系统可能会提示用户通过显式用户中介(使用 mediation: required 的流程)登录。

用户通过 FedCM 自动重新身份验证。

使用 preventSilentAccess() 强制执行中介

在用户退出账号后立即自动重新验证用户身份,并不能提供非常良好的用户体验。因此,FedCM 在自动重新验证后会有 10 分钟的静默期,以防止此行为。这意味着,除非用户在 10 分钟内重新登录,否则系统每 10 分钟最多会自动重新授权一次。当用户明确退出 RP(例如,点击“退出”按钮)时,RP 应调用 navigator.credentials.preventSilentAccess() 以明确请求浏览器停用自动重新授权。

function signout() {
  navigator.credentials.preventSilentAccess();
  location.href = '/signout';
}

用户可以在设置中选择停用自动重新授权

用户可以在“设置”菜单中选择停用自动重新授权:

  • 在桌面版 Chrome 中,依次选择 chrome://password-manager/settings > 自动登录。
  • 在 Android Chrome 中,依次打开设置 > 密码管理工具 > 点按右上角的齿轮图标 > 自动登录。

通过停用此切换开关,用户可以完全停用自动重新授权行为。如果用户在 Chrome 实例中登录了 Google 账号并启用了同步功能,系统会存储此设置并在设备间同步。

断开 IdP 与 RP 之间的连接

如果用户之前通过 FedCM 使用 IdP 登录了 RP,浏览器会在本地将该关系记忆为已关联账号的列表。RP 可以通过调用 IdentityCredential.disconnect() 函数来发起断开连接。此函数可从顶级 RP 帧调用。RP 需要传递 configURL、在 IdP 下使用的 clientId 以及 accountHint,以便 IdP 断开连接。账号提示可以是任意字符串,只要断开连接端点可以识别账号即可,例如电子邮件地址或用户 ID,该 ID 不一定与账号列表端点提供的账号 ID 相匹配:

// 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() 会返回 Promise。此 promise 可能会因以下原因抛出异常:

  • 用户尚未通过 FedCM 使用 IdP 登录 RP。
  • 从不含 FedCM 权限政策的 iframe 中调用 API。
  • config网址 无效或缺少断开连接端点。
  • 内容安全政策 (CSP) 检查失败。
  • 有一个待处理的解除关联请求。
  • 用户已在浏览器设置中停用 FedCM。

身份提供方的断开连接端点返回响应时,浏览器上的 RP 和 IdP 会断开连接,并且 Promise 会解析。断开连接的账号的 ID 在断开连接端点的响应中指定。

从跨源 iframe 内调用 FedCM

您可以使用 identity-credentials-get 权限政策从跨源 iframe 中调用 FedCM(如果父级框架允许)。为此,请将 allow="identity-credentials-get" 属性附加到 iframe 代码中,如下所示:

<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>

您可以在示例中查看其实际运作情况。

(可选)如果父级帧想要限制调用 FedCM 的来源,请发送包含允许来源列表的 Permissions-Policy 标头。

Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")

您可以参阅使用权限政策控制浏览器功能,详细了解“权限”政策的运作方式。