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
通过 Chrome 设置阻止第三方 Cookie

在 FedCM 实际生效之前,您可以在 Chrome 上测试 FedCM 在没有第三方 Cookie 的情况下的运作方式。

如需屏蔽第三方 Cookie,请使用无痕模式,或在桌面设备上前往 chrome://settings/cookies 选择“屏蔽第三方 Cookie”,或在移动设备上前往设置 > 网站设置 > 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 支持多个账号,此端点将返回所有已登录的账号。

浏览器发送包含 SameSite=None 的 Cookie 的 GET 请求,但不包含 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(可选) RP 提供的请求 Nonce。
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 对话框。

当用户点击继续按钮时,浏览器会打开一个弹出式窗口,显示 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(可选) 通过指定 accounts 端点提供的 domain_hints 值之一,FedCM 对话框会选择性地显示指定的账号。

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

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

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

当 RP 调用 navigator.credentials.get() 时,系统会执行以下活动:

  1. 浏览器发送请求并提取多个文档:
    1. well-known 文件和用于声明端点的 IdP 配置文件
    2. 账号列表
    3. 可选:从客户端元数据端点检索到的 RP 隐私权政策和服务条款的网址。
  2. 浏览器会显示用户可以用来登录的账号列表,以及服务条款和隐私权政策(如果有)。
  3. 用户选择用于登录的账号后,系统会向 IdP 发送 ID 断言端点请求,以检索令牌。
  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 navigator.credentials.get() 后立即尝试自动重新对用户进行身份验证。

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

这有助于评估 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")

如需详细了解权限政策的运作方式,请参阅使用权限政策控制浏览器功能