隆重推出适用于 Chrome 中的 WebAuthn 的提示、相关源请求和 JSON 序列化

Chrome 128 和 129 为 WebAuthn 引入了一些激动人心的新功能, 构建基于通行密钥的身份验证系统。

  • 提示:提示可让信赖方 (RP) 更好地控制 WebAuthn 浏览器的界面。对于需要 使用安全密钥。
  • 相关源站请求:具有相关源站 请求,RP 可以使通行密钥在多个网域上有效。如果您拥有多个 那么现在您可以允许用户在各个网站上重复使用通行密钥 从而消除登录障碍
  • JSON 序列化:JSON 序列化 API 可让您通过编码和解码选项来简化 RP 的前端代码, WebAuthn API 来传递和传递凭据。

提示

借助 hints,依赖方 (RP) 现在可以指定用于创建 或者使用通行密钥进行身份验证

以前,当 RP 想要限制用户可以使用的身份验证器时, 创建通行密钥或进行身份验证 authenticatorSelection.authenticatorAttachment 用于指定 "platform",或 "cross-platform"。它们分别将身份验证器限制在一个平台 身份验证器漫游 身份验证器。 借助 hints,此规范可以更加灵活。

RP 可以使用 PublicKeyCredentialCreationOptions 中的可选 hintsPublicKeyCredentialRequestOptions 用于指定 "security-key", 数组中按偏好顺序排列的 "client-device""hybrid"

以下是一个凭据创建请求示例, 使用 "security-key" 作为提示的 "cross-platform" 身份验证器。这说明 Chrome 为企业用户显示侧重于安全密钥的界面。

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    hints: ['security-key'],
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
<ph type="x-smartling-placeholder">
</ph> 通过指定“security-key”作为提示,浏览器会显示一个以安全密钥为中心的对话框。
通过指定“security-key”作为提示,浏览器会显示一个以安全密钥为中心的对话框。

当 RP 想要优先考虑跨设备验证场景时,可以 发送优先使用 "cross-platform" 个身份验证器的身份验证请求 并使用 "hybrid" 作为提示。

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    residentKey: true,
    hints: ['hybrid']
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
<ph type="x-smartling-placeholder">
</ph> 通过指定“hybrid”作为提示,浏览器会显示一个以跨设备登录为重点的对话框。
通过指定“hybrid”作为提示,浏览器会显示一个以跨设备登录为重点的对话框。

相关来源 请求,RP 可以 确保通行密钥可在多个网域中使用构建集中式登录 和使用联合协议仍是推荐解决方案, 。但是,如果您拥有多个网域且无法实现联合 可能是一种解决方案

所有 WebAuthn 请求都必须指定信赖方 ID (RP ID) 以及所有通行密钥 都与单个 RP ID 相关联。以前,源只能指定 RP ID,在这种情况下,www.example.co.uk 可以指定 RP ID 为 example.co.uk,但不是 example.com。有相关来源 请求,可以通过提取众所周知的 JSON 文件来验证已声明的 RP ID 位于目标网域的 /.well-known/webauthn 中。所以example.co.uk (以及 example.inexample.de 等)都可以使用 RP ID 如果 example.com 按以下格式指定它们,则为 example.com

URL:https://example.com/.well-known/webauthn

{
  "origins": [
    "https://example.co.uk",
    "https://example.de",
    "https://example.sg",
    "https://example.net",
    "https://exampledelivery.com",
    "https://exampledelivery.co.uk",
    "https://exampledelivery.de",
    "https://exampledelivery.sg",
    "https://myexamplerewards.com",
    "https://examplecars.com"
  ]
}

如需了解如何设置相关源请求,请参阅允许在 Google Play 中重复使用通行密钥 具有相关来源的网站 请求

JSON 序列化

WebAuthn 请求和响应对象有多个字段,其中包含原始的 ArrayBuffer 中的二进制数据,例如凭据 ID、用户 ID 或质询。 如果网站想使用 JSON 来与其服务器交换此类数据,则二进制文件 数据必须先进行编码,例如使用 Base64网址。这会增加不必要的 对于想要开始在自家网站上使用通行密钥的开发者而言,这非常复杂。

WebAuthn 现在提供 API 来解析 PublicKeyCredentialCreationOptionsPublicKeyCredentialRequestOptions WebAuthn 直接从 JSON 请求对象,并将 PublicKeyCredential 转换为 JSON。所有带有原始二进制文件的 ArrayBuffer 值字段 数据会自动与 Base64网址 编码的值相互转换。 Chrome 129 及更高版本提供这些 API。

在创建通行密钥之前,请先提取 JSON 编码的 PublicKeyCredentialCreationOptions 对象,并使用 PublicKeyCredential.parseCreationOptionsFromJSON()

浏览器支持

  • Chrome:129。 <ph type="x-smartling-placeholder">
  • 边缘:129。 <ph type="x-smartling-placeholder">
  • Firefox:119。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

来源

export async function registerCredential() {

  // Fetch encoded `PublicKeyCredentialCreationOptions`
  // and JSON decode it.
  const options = await fetch('/auth/registerRequest').json();

  // Decode `PublicKeyCredentialCreationOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseCreationOptionsFromJSON(options);  

  // Invoke the WebAuthn create() function.
  const cred = await navigator.credentials.create({
    publicKey: decodedOptions,
  });
  ...

创建通行密钥后,使用 toJSON() 对生成的凭据进行编码, 以便将其发送到服务器

浏览器支持

  • Chrome:129。 <ph type="x-smartling-placeholder">
  • 边缘:129。 <ph type="x-smartling-placeholder">
  • Firefox:119。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

来源

  ...
  const cred = await navigator.credentials.create({
    publicKey: options,
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch('/auth/registerResponse', credential);
  ...

在使用通行密钥进行身份验证之前,请提取 JSON 编码的 PublicKeyRequestCreationOptions,并使用 PublicKeyCredential.parseRequestOptionsFromJSON()

浏览器支持

  • Chrome:129。 <ph type="x-smartling-placeholder">
  • 边缘:129。 <ph type="x-smartling-placeholder">
  • Firefox:119。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

来源

export async function authenticate() {

  // Fetch encoded `PublicKeyCredentialRequestOptions`
  // and JSON decode it.
  const options = await fetch('/auth/signinRequest').json();

  // Decode `PublicKeyCredentialRequestOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseRequestOptionsFromJSON(options);

  // Invoke the WebAuthn get() function.
  const cred = await navigator.credentials.get({
    publicKey: options
  });
  ...

使用通行密钥进行身份验证后,使用 toJSON() 方法,以便将其发送到服务器。

浏览器支持

  • Chrome:129。 <ph type="x-smartling-placeholder">
  • 边缘:129。 <ph type="x-smartling-placeholder">
  • Firefox:119。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

来源

  ...
  const cred = await navigator.credentials.get({
    publicKey: options
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch(`/auth/signinResponse`, credential);
  ...

了解详情

如需详细了解 WebAuthn 和通行密钥,请查看以下资源: