FedCM 更新:IdP Sign-In Status API、登录提示等

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 支持多个帐号,它会列出所有已登录的帐号。

显示多个用户帐号的 FedCM 对话框。
显示多个用户帐号的 FedCM 对话框

用户登录后,有时依赖方 (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 在此网站上注册时。

“使用 Google 账号登录”按钮。
“使用 Google 账号登录”按钮
个性化的“使用 Google 账号登录”按钮。
个性化“使用 Google 账号登录”按钮

问题在于,由于个性化按钮依赖于 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 对话框界面中的字符串,以便它可以适应预定义的身份验证上下文。请参阅以下屏幕截图,了解不同的选项:

使用 呈现的 FedCM 对话框
呈现了“Sign in to ****”的 FedCM 对话框。如果未指定 RP Context,这是默认选项。
使用 呈现的 FedCM 对话框
显示“Sign up to ****”的 FedCM 对话框
使用 呈现的 FedCM 对话框
显示“Continue to ****”的 FedCM 对话框
使用 呈现的 FedCM 对话框
使用“Use ****”呈现的 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 的 FedCM 对话框。
一个建议登录 IdP 的 FedCM 对话框。

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

点击“登录 IdP”按钮后显示的弹出式窗口。
点击“登录 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();
}
用户在使用 FedCM 登录 IdP 后登录了 RP

您可以在我们的演示中试用 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 注册源试用

  1. 前往源试用注册页面
  2. 点击注册按钮,然后填写相应表单以请求令牌。
  3. 输入 IdP 的 Web Origin(网络来源)。
  4. 点击提交
  5. origin-trial <meta> 标记添加到使用 IdentityProvider.close() 的网页的标头中。例如,其格式可能如下所示:
    <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">

为 RP 注册第三方源试用

  1. 前往源试用注册页面
  2. 点击注册按钮,然后填写相应表单以请求令牌。
  3. 输入 IdP 的 Web Origin(网络来源)。
  4. 选中第三方匹配,以在其他源上通过 JavaScript 注入令牌。
  5. 点击提交
  6. 将颁发的令牌嵌入到第三方网站中。

如需将令牌嵌入第三方网站,请将以下代码添加到从 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 用户)