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 Sign-InStatus API 启动源试用。IdP Sign-in status API 是一项强制性要求,在交付时将是一项重大变更。如果您已有 FedCM 实现,请务必参与源试用。
登录提示 API
调用 FedCM 时,浏览器会显示来自指定身份提供方 (IdP) 的已登录帐号。如果 IdP 支持多个帐号,它会列出所有已登录的帐号。
用户登录后,有时依赖方 (RP) 会要求用户重新进行身份验证。但用户可能不确定自己使用的是哪个帐号。 如果 RP 可以指定要登录的账号,用户选择账号会更加轻松。登录提示在 Chrome 116 中提供,并且 RP 可以将列表范围缩小到 1。
此扩展程序会在来自 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"
}]
}
});
用户信息 API
装饰有 IdP 徽标的登录按钮现在很常见,以便用户使用身份联合登录。但是,使用用户个人资料图标及其信息装饰按钮,会更加直观,便于用户登录,尤其是当用户之前通过 IdP 在此网站上注册时。
问题在于,由于个性化按钮依赖于 iframe 中 IdP 网域上的第三方 Cookie 来识别已登录用户来呈现该按钮,因此在第三方 Cookie 被弃用后,个性化按钮将无法使用。
User Info API 在 Chrome 116 中提供,可让 IdP 在不依赖第三方 Cookie 的情况下从服务器获取回访用户的信息。
IdP 应从 RP 网站上嵌入的 iframe 中调用该 API,以便检索用户信息并呈现个性化按钮,就像它是 RP surface 的一部分一样。通过此 API 调用,浏览器会向帐号列表端点发出请求,然后在以下情况下返回一个用户信息的数组:
- 用户过去曾在同一浏览器实例上通过 IdP 通过 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
Chrome 116 中提供的 RP Context API 允许 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 从 Chrome 116 开始在桌面设备上启动 IdP Sign-In status API 源试用,随后在 Android Chrome 中结束试用。借助源试用功能,您可以使用新功能或实验性功能来构建功能,让用户在限定时间内试用这些功能,然后再面向所有用户推出相应功能。
IdP Sign-In status API 是一种机制,通过这种机制,IdP 可将用户在 IdP 上的登录状态告知浏览器。借助此 API,浏览器可以减少对 IdP 的不必要请求,并缓解潜在的计时攻击。
将用户的登录状态告知浏览器
IdP 可以通过以下两种方式向浏览器表明用户的登录状态:发送 HTTP 标头或调用 JavaScript API;当用户已在 IdP 中登录;或用户已退出其所有 IdP 帐号后。浏览器会将状态记录为以下状态之一:“sign-in”“sign-out”或“unknown”(默认)。
如需表明用户已登录,请在顶级导航或同源子资源请求中发送 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()
这些操作会将用户的登录状态记录为“退出”。当用户的登录状态为“退出”时,如果不向 IdP 的帐号列表端点发出请求,调用 FedCM 会静默失败。
默认情况下,IdP 登录状态会设置为“未知”。在 IdP 使用 IdP Sign-InStatus API 发送信号之前,会使用此状态。我们引入此状态是为了更好地完成过渡,因为在我们推出此 API 时,用户可能已经登录了 IdP,而 IdP 可能没有机会在首次调用 FedCM 时向浏览器发出信号。在这种情况下,我们会向 IdP 的帐号列表端点发出请求,并根据来自帐号列表端点的响应更新状态:
- 如果端点返回活跃帐号列表,请将状态更新为“登录”并打开 FedCM 对话框以显示这些帐号。
- 如果端点未返回任何帐号,请将状态更新为“退出”,并使 FedCM 调用失败。
如果用户会话过期,该怎么办?让用户通过动态登录流程登录
即使 IdP 会继续将用户的登录状态告知浏览器,也可能不同步,例如当会话过期时。当登录状态为“登录”时,浏览器会尝试向帐号列表端点发送一个设置了凭据的请求,但服务器拒绝了该请求,因为会话已不再可用。在这种情况下,浏览器可以通过弹出式窗口动态让用户登录 IdP。
FedCM 对话框将显示一条消息,如下图所示:
点击继续按钮后,浏览器会打开一个弹出式窗口,将用户定向到 IdP 的登录页面。
您可以在 IdP 配置文件中使用 signin_url
指定登录页面网址(必须是 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 Sign-In status API 的行为。会话会在您登录演示 IdP 后的三分钟内过期。然后,您可以通过弹出式窗口行为观察登录 IdP 的操作。
参与源试用
您可以在 Chrome 116 或更高版本中开启 Chrome
标志
chrome://flags#fedcm-idp-signin-status-api
,
在本地试用 IdP Sign-InStatus API。
您还可以通过注册两次源试用来启用 IdP Sign-In status API:
借助源试用,您可以试用新功能,并针对其易用性、实用性和有效性向 Web 标准社区提供反馈。如需了解详情,请参阅面向 Web 开发者的源试用指南。
IdP Sign-InStatus API 源试用从 Chrome 116 至 Chrome 119 有效。
为 IdP 注册源试用
- 前往源试用注册页面。
- 点击注册按钮,然后填写相应表单以请求令牌。
- 输入 IdP 的 Web Origin(网络来源)。
- 点击提交。
- 将
origin-trial
<meta>
标记添加到使用IdentityProvider.close()
的网页的标头中。例如,其格式可能如下所示:
<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
。
为 RP 注册第三方源试用
- 前往源试用注册页面。
- 点击注册按钮,然后填写相应表单以请求令牌。
- 输入 IdP 的 Web Origin(网络来源)。
- 选中第三方匹配,以在其他源上通过 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 分享。
照片提供者:Dan Cristian Pădure(由 Unsplash 用户)