Chrome 116 提供了 FedCM 功能,例如 Login Hint API、User Info API 和 RP Context API,并开始了 IdP Sign-In Status API 的源代码试用。
在 Chrome 116 中,Chrome 将推出以下三项新的联合身份验证管理 (FedCM) 功能:
- Login Hint API:指定要登录的首选用户账号。
- User Info API:提取回访用户的信息,以便身份提供方 (IdP) 在 iframe 中呈现个性化的登录按钮。
- RP Context API:在 FedCM 对话框中使用与“登录”不同的标题。
此外,Chrome 还将开始针对 IdP 登录状态 API 开展源代码试用。IdP 登录状态 API 是一项必需功能,发布后将是一项重大变更。如果您已实现 FedCM,请务必参与源试用。
Login Hint API
调用 FedCM 时,浏览器会显示指定身份提供方 (IdP) 中的已登录账号。如果 IdP 支持多个账号,则会列出所有已登录的账号。

用户登录后,依赖方 (RP) 有时会要求用户重新进行身份验证。但用户可能不确定自己一直在使用哪个账号。如果 RP 可以指定要使用哪个账号登录,用户便可以更轻松地选择账号。登录提示将在 Chrome 116 中发布,借助该功能,RP 可以将列表缩小到一个。
此扩展程序会在来自 IdP 的账号列表端点响应中添加一个 login_hints
数组,其中包含 IdP 支持的所有可能的过滤条件类型。例如,当 IdP 支持按电子邮件地址和 ID 进行过滤时,账号响应可能如下所示:
{
"accounts": [{
"id": "demo1",
"email": "demo1@example.com",
"name": "John Doe",
"login_hints": ["demo1", "demo1@example.com"],
...
}, {
"id": "demo2",
"email": "demo2@example.com",
"name": "Jane Doe",
"login_hints": ["demo2", "demo2@example.com"],
...
}, ...]
}
通过在账号列表中传递 login_hints
,RP 可以使用 loginHint
属性调用 navigator.credentials.get()
,如以下代码示例所示,以选择性显示指定的账号:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/manifest.json",
clientId: "123",
nonce: nonce,
loginHint : "demo1@example.com"
}]
}
});
User Info API
现在,带有 IdP 徽标的登录按钮很常见,用户可以通过身份联合功能登录。不过,使用用户的个人资料图标和信息装饰按钮,可以让用户更直观地登录,尤其是当用户之前已使用 IdP 在该网站上注册过时。


问题在于,由于个性化按钮依赖于 iframe 中 IdP 网域上的第三方 Cookie 来识别已登录的用户以呈现按钮,因此在第三方 Cookie 被弃用后,该按钮将无法使用。
User Info API 将在 Chrome 116 中发布,可让 IdP 从服务器获取回访用户的信息,而无需依赖第三方 Cookie。
IdP 应从 RP 网站上嵌入的 iframe 中调用此 API,以便检索用户信息并呈现个性化按钮,就像它是 RP 界面的一部分一样。通过该 API 调用,浏览器会向账号列表端点发出请求,然后在满足以下条件时返回一组用户信息:
- 用户之前在同一浏览器实例中通过 FedCM 使用 IdP 登录了 RP,并且数据尚未清除。
- 用户在同一浏览器实例中登录了 IdP。
// Iframe displaying a page from the https://idp.example origin
const user_info = await IdentityProvider.getUserInfo({
configUrl: "https://idp.example/fedcm.json",
clientId: "client1234"
});
// IdentityProvider.getUserInfo returns an array of user information.
if (user_info.length > 0) {
// Chrome puts returning accounts first, so the first account received is guaranteed to be a returning account.
const name = user_info[0].name;
const given_name = user_info[0].given_name;
const display_name = given_name ? given_name : name;
const picture = user_info[0].picture;
const email = user_info[0].email;
// Renders the personalized sign-in button with the information above.
}
请注意,若要允许从与 IdP 同源的 iframe 中调用 IdentityProvider.getUserInfo()
,嵌入的 HTML 必须通过 identity-credentials-get
权限政策明确允许。
<iframe src="https://fedcm-idp-demo.glitch.me" allow="identity-credentials-get"></iframe>
您可以访问 https://fedcm-rp-demo.glitch.me/button,查看其实际运行情况。
RP Context API
RP Context API 在 Chrome 116 中发布,可让 RP 修改 FedCM 对话框界面中的字符串,以便适应预定义的身份验证上下文。请参阅以下屏幕截图,了解不同的选项:




使用方法很简单;为 identity.context
属性提供 "signin"
(默认值)、"signup"
、"use"
或 "continue"
之一。
const credential = await navigator.credentials.get({
identity: {
// "signin" is the default, "signup", "use" and "continue"
// can also be used
context: "signup",
providers: [{
configURL: "https://idp.example/fedcm.json",
clientId: "1234",
}],
}
});
IdP Sign-In Status API 源试用
从 Chrome 116 开始,Chrome 在桌面设备上启动 IdP Sign-In Status API 源试用,之后 Android 版 Chrome 也将启动该试用。借助源试用,您可以使用新功能或实验性功能来构建功能,让用户可以在该功能面向所有人发布之前限时试用。
IdP 登录状态 API 是一种机制,用于让 IdP 告知浏览器用户在 IdP 上的登录状态。借助此 API,浏览器可以减少对 IdP 的不必要请求,并减少潜在的时间攻击。
告知浏览器用户的登录状态
当用户在 IdP 上登录或退出所有 IdP 账号时,IdP 可以通过发送 HTTP 标头或调用 JavaScript API 向浏览器发送用户的登录状态信号。浏览器会将状态记录为以下之一:“登录”“退出”或“未知”(默认)。
如需指示用户已登录,请在顶级导航或同源子资源请求中发送 IdP-SignIn-Status: action=signin
HTTP 标头:
IdP-SignIn-Status: action=signin
或者,您也可以从 IdP 来源调用 JavaScript API IdentityProvider.login()
:
IdentityProvider.login()
这些事件会将用户的登录状态记录为“登录”。当用户的登录状态设置为“已登录”时,调用 FedCM 的 PR 会向 IDP 的账号列表端点发出请求,并在 FedCM 对话框中向用户显示可用账号。
如需指明用户已退出其所有账号,请在顶级导航或同源子资源请求中发送 IdP-SignIn-Status: action=signout-all
HTTP 标头:
IdP-SignIn-Status: action=signout-all
或者,您也可以从 IdP 来源调用 JavaScript API IdentityProvider.logout()
:
IdentityProvider.logout()
这些事件会将用户的登录状态记录为“退出”。当用户的登录状态为“退出登录”时,调用 FedCM 会静默失败,而不会向 IdP 的账号列表端点发出请求。
默认情况下,IdP 登录状态设为“未知”。在 IdP 使用 IdP 登录状态 API 发送信号之前,会使用此状态。我们引入此状态是为了更好地实现过渡,因为在我们发布此 API 时,用户可能已经登录了 IdP,而 IdP 在首次调用 FedCM 时可能没有机会向浏览器发出此信号。在本例中,我们会向 IdP 的账号列表端点发出请求,并根据账号列表端点的响应更新状态:
- 如果端点返回有效账号列表,请将状态更新为“登录”,然后打开 FedCM 对话框以显示这些账号。
- 如果端点未返回任何账号,请将状态更新为“退出”,并使 FedCM 调用失败。
如果用户会话过期,会怎么样?允许用户通过动态登录流程登录
即使 IdP 继续向浏览器告知用户的登录状态,但状态也可能会不同步,例如在会话过期时。当登录状态为“已登录”时,浏览器会尝试向账号列表端点发送包含凭据的请求,但由于会话不再可用,服务器会拒绝该请求。在这种情况下,浏览器可以动态允许用户通过弹出式窗口登录 IdP。
FedCM 对话框会显示一条消息,如下图所示:

点击继续按钮后,浏览器会打开一个弹出式窗口,将用户定向到 IdP 的登录页面。

您可以使用 signin_url
在 IdP 配置文件中指定登录页面网址(必须是 IdP 的来源)。
{
"accounts_endpoint": "/auth/accounts",
"client_metadata_endpoint": "/auth/metadata",
"id_assertion_endpoint": "/auth/idtokens",
"signin_url": "/signin"
}
}
弹出式窗口是使用第一方 Cookie 的常规浏览器窗口。 内容窗口中发生的任何情况都取决于 IdP,但没有窗口句柄可用于向 RP 页面发出跨源通信请求。用户登录后,IdP 应:
- 发送
IdP-SignIn-Status: action=signin
标头或调用IdentityProvider.login()
API 以告知浏览器用户已登录。 - 调用
IdentityProvider.close()
以关闭自身(弹出式窗口)。
// User is signed in...
// Don't forget feature detection.
if (IdentityProvider) {
// Signal to the browser that the user has signed in.
IdentityProvider.close();
}
您可以在我们的演示中试用 IdP 登录状态 API 行为。您登录演示版 IdP 后,会话将在 3 分钟后过期。然后,您可以通过弹出式窗口行为观察对 IdP 的登录。
参与源试用
您可以在本地试用 IdP 登录状态 API,方法是在 Chrome 116 或更高版本中开启 Chrome 标志chrome://flags#fedcm-idp-signin-status-api
。
您还可以通过两次注册来源试用来启用 IdP 登录状态 API:
通过源试用,您可以试用新功能,并向 Web 标准社区提供有关其易用性、实用性和有效性的反馈。如需了解详情,请参阅面向 Web 开发者的源代码试用指南。
IdP Sign-In Status API 源试用从 Chrome 116 到 Chrome 119 均可用。
为 IdP 注册源试用
- 前往原始版本试用版注册页面。
- 点击注册按钮,然后填写表单以请求令牌。
- 将 IdP 的来源输入为网站来源。
- 点击提交。
- 将
origin-trial
<meta>
标记添加到使用IdentityProvider.close()
的网页的标头中。例如,可能如下所示:
<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
。
为 RP 注册第三方来源试用
- 前往原始版本试用版注册页面。
- 点击注册按钮,然后填写表单以请求令牌。
- 将 IdP 的来源输入为网站来源。
- 选中第三方匹配,以便使用 JavaScript 在其他来源上注入令牌。
- 点击提交。
- 将所发放的令牌嵌入到第三方网站中。
如需在第三方网站上嵌入令牌,请将以下代码添加到从 IdP 源提供的 JavaScript 库或 SDK 中。
const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);
将 TOKEN_GOES_HERE
替换为您自己的令牌。
互动和分享反馈
如果您有任何反馈或在测试期间遇到任何问题,可以访问 crbug.com 与我们分享。
照片由 Unsplash 用户 Dan Cristian Pădureț 拍摄