FedCM 更新:Login Status API、Error API 和 Auto-selected Flag API

Chrome 120 即将搭载 FedCM 的 Login Status API。 Login Status API(以前称为 IdP Sign-in Status API)允许网站、 (尤其是身份提供方)在用户登录其网站时向浏览器发送 登录和退出。FedCM 使用此信号来应对静默定时攻击 这样,FedCM 就可以在没有第三方 Cookie。这个 update 解决了我们之前最后剩下的不向后兼容的更改 在最初的发货意向 FedCM 纳入我们的工作范围

虽然 Login Status API 可改善隐私保护属性和易用性,但 发布之后的不向后兼容更改。如果您已有 FedCM,请务必使用以下 操作说明。

此外,Chrome 还推出了两种新的 Federated Credential Management (FedCM) 功能:

  • Error API:使用原生界面在用户尝试登录失败时通知用户 。
  • Auto-Selected Flag API:通知身份提供方 (IdP) 以及信赖方 (RP)(如果在流程中自动选择了凭据)。

登录状态 API

Login Status API 是一种机制,可供网站(尤其是 IdP) 浏览器,确认用户在 IdP 上的登录状态。利用此 API,浏览器可以 减少向 IdP 发出的不必要的请求,并缓解潜在的计时攻击。

告知浏览器用户的登录状态

IdP 可以通过发送 HTTP 标头向浏览器表明用户的登录状态 或者在用户在 IdP 上登录,或在 用户已退出其所有 IdP 账号。对于每个 IdP(由其 配置网址),则浏览器会保留表示登录状态的三种状态变量 可能的值包括 logged-inlogged-outunknown。默认状态 为 unknown

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

Set-Login: logged-in

或者,您也可以调用 JavaScript API navigator.login.setStatus('logged-in') 从 IdP 来源导入:

navigator.login.setStatus('logged-in');

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

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

Set-Login: logged-out

或者,从 IdP 调用 JavaScript API navigator.login.setStatus('logged-out') 来源:

navigator.login.setStatus('logged-out');

这些调用会将用户的登录状态记录为 logged-out。当用户登录时 状态为 logged-out,则调用 FedCM 时会静默失败,而不会执行 发送到 IdP 的账号列表端点。

unknown 状态是在 IdP 使用“登录”发送信号之前设置的 Status API。我们引入此状态是为了获得更好的转换效果,因为用户可能 在我们提供此 API 时已经登录到 IdP。IdP 可能 有机会在首次调用 FedCM 时向浏览器发出信号。在 在本例中,我们会向 IdP 的账号列表端点发出请求,并更新 返回状态:

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

如果用户会话过期了怎么办?让用户通过动态登录流程登录!

尽管 IdP 会不断将用户的登录状态告知浏览器, 状态可能不同步,例如会话过期。浏览器会尝试 在用户登录时向账号列表端点发送 状态为 logged-in,但服务器未返回任何账号,因为会话 不再可用。在这种情况下,浏览器会动态地 用户通过对话框窗口登录 IdP。

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

<ph type="x-smartling-placeholder">
</ph> 建议登录 IdP 的 FedCM 对话框。
建议登录 IdP 的 FedCM 对话框。

当用户点击 Continue 按钮时,浏览器会打开一个对话框以供 IdP 的登录页面。

<ph type="x-smartling-placeholder">
</ph> 示例对话框。
点击“登录 IdP”按钮后显示的对话框示例。
。 <ph type="x-smartling-placeholder">

登录页面网址使用 login_url 作为 IdP 配置的一部分指定 文件

{
  "accounts_endpoint": "/auth/accounts",
  "client_metadata_endpoint": "/auth/metadata",
  "id_assertion_endpoint": "/auth/idtokens",
  "login_url": "/login"
  }
}

该对话框是包含第一方 Cookie 的常规浏览器窗口。不限 对话框中发生的事件取决于 IdP,且没有可用的窗口句柄 向 RP 页面发出跨源通信请求。在用户 则 IdP 应执行以下操作:

  • 发送 Set-Login: logged-in 标头或调用 navigator.login.setStatus("logged-in") API,用于告知浏览器 个用户已经登录。
  • 调用 IdentityProvider.close() 以关闭对话框。
。 <ph type="x-smartling-placeholder">
</ph> 用户在使用 FedCM 登录 IdP 后登录 RP。
用户在使用 FedCM 登录 IdP 后登录 RP。
。 <ph type="x-smartling-placeholder">

您可以在我们的 演示

  1. 点按转到 IdP 并登录按钮。
  2. 使用任意账号登录。
  3. 账号状态下拉菜单中选择会话已过期
  4. 更新个人信息按钮。
  5. 点按访问 RP 以试用 FedCM 按钮。

您应该能够通过模块行为观察到 IdP 的登录行为。

错误 API

当 Chrome 向 ID 断言端点发送请求时(例如,当 用户点击 FedCM 界面上的使用以下身份继续按钮或进行自动重新身份验证 则 IdP 可能会出于正当理由无法颁发令牌。 例如,如果客户端未获得授权,则服务器会暂时 “不可用”等目前,如果出现以下情况,Chrome 会静默失败请求 此类错误,并且仅通过拒绝 promise 来通知 RP。

借助 Error API,Chrome 通过显示原生界面来通知用户,该界面包含 IdP。

<ph type="x-smartling-placeholder">
</ph> 一个 FedCM 对话框,显示了用户登录尝试失败后显示的错误消息。该字符串与错误类型相关联。
显示用户登录尝试失败后错误消息的 FedCM 对话框。该字符串与错误类型相关联。

IdP HTTP API

id_assertion_endpoint 响应中,IdP 可以将令牌返回给 如果可以应要求发出,则不可以。在此方案中,如果一个令牌 则 IdP 可能会返回“错误”其中包含两个新的 选填字段:

  1. code
  2. url
// id_assertion_endpoint response
{
  "error": {
     "code": "access_denied",
     "url": "https://idp.example/error?type=access_denied"
  }
}

对于代码,IdP 可以从 OAuth 2.0 中选择一种已知错误。 指定的错误 列表 [invalid_requestunauthorized_clientaccess_deniedserver_errortemporarily_unavailable] 或使用任意字符串。如果是后者,则 Chrome 呈现带有一般错误消息的错误界面,并将代码传递给 RP

对于 url,它标识人类可读的网页,其中包含有关 来向用户提供有关该错误的更多信息。此字段为 因为浏览器无法以原生方式提供丰富的错误消息, 界面。例如,后续步骤链接、客户服务联系信息和 依此类推。如果用户想详细了解错误详情和修正方法, 他们可以从浏览器界面访问所提供的页面了解详情。网址 必须与 IdP configURL 位于同一网站。

<ph type="x-smartling-placeholder">
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;
}

自动选择的 Flag API

mediation: optional默认用户中介 行为 ,当出现以下情况时,它会触发自动重新身份验证: 不过,系统可能会自动重新验证 不可用的 只有浏览器知道无法使用时,系统可能会提示用户登录 显式用户中介,这是具有不同属性的流程。

  • 从 API 调用方的角度来看,当他们收到 ID 令牌时, 了解这是否是自动重新身份验证的结果 。这让他们很难评估 API 性能并改进 打造相应的用户体验。
  • 从 IdP 的角度来看,他们同样无法确定 进行性能评估。此外, 是否涉及显式用户中介是否有助于他们支持更多 安全相关功能例如,有些用户可能更喜欢 该安全层级要求在身份验证中明确进行用户中介。如果 IdP 在没有此类中介的情况下收到令牌请求, 请求。例如,返回一个错误代码,以便 RP 可以 使用 mediation: required 再次调用 FedCM API。

因此,提供自动重新身份验证流程的可见性 让开发者受益

借助 Auto-selected Flag API, Chrome 会分享是否通过点按 每当自动重新进行身份验证时,同时提供 IdP 和 RP 的继续登录按钮 或出现了明确的中介。仅在用户 权限。

IdP 共享

为了将信息分享给 IdP 用户获取权限后,Chrome 会添加 POST 请求中的 is_auto_selected=true,发送至 id_assertion_endpoint:

POST /fedcm_assertion_endpoint HTTP/1.1
Host: 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=Ct0D&disclosure_text_shown=true&is_auto_selected=true

RP 共享

浏览器可以通过以下方式将信息分享给 isAutoSelected 中的 RP: IdentityCredential

const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/manifest.json',
      clientId: '1234'
    }]
  }
});

if (cred.isAutoSelected !== undefined) {
  const isAutoSelected = cred.isAutoSelected;
}

互动和分享反馈

如果您有反馈意见或在测试期间遇到任何问题,欢迎分享 在 crbug.com.

照片提供者:Girl 带红色帽子的Un 创立文