通行密钥与 特定网站相关联,只能用于登录创建时对应的网站。
这在依赖方
ID (RP ID) 中指定,对于为 example.com 网域创建的通行密钥,RP ID 可以是 www.example.com 或 example.com。
虽然 RP ID 可防止通行密钥被用作在任何地方进行身份验证的单一凭据,但它们会给以下情况带来问题:
- 具有多个网域的网站:用户无法使用同一通行密钥登录由同一公司管理的不同国家/地区特定网域(例如
example.com和example.co.uk)。 - 品牌网域:用户无法在单个品牌使用的
不同网域(例如
acme.com和acmerewards.com)中使用同一凭据。 - 移动应用:移动应用通常没有自己的网域,因此 凭据管理具有挑战性。
有一些基于身份联合的变通方案,还有一些基于 iframe 的变通方案,但在某些情况下,这些方案不太方便。相关来源请求提供了一种解决方案。
解决方案
借助 相关来源请求, 网站可以指定允许使用其 RP ID 的来源。
这样,用户就可以在您运营的多个网站上重复使用同一通行密钥。
如需使用相关来源请求,您需要在特定网址 https://{RP ID}/.well-known/webauthn 上提供一个特殊的 JSON 文件。如果 example.com 想要
允许其他来源将其用作 RP ID,则应在 https://example.com/.well-known/webauthn: 上提供以下
文件:
{
"origins": [
"https://example.co.uk",
"https://example.de",
"https://example-rewards.com"
]
}
下次,当任何这些网站调用通行密钥创建 (navigator.credentials.create) 或身份验证 (navigator.credentials.get) 时,如果使用 example.com 作为 RP ID,浏览器会注意到 RP ID 与发出请求的来源不匹配。如果浏览器支持相关来源
请求,它首先会在 https://{RP ID}/.well-known/webauthn 中查找 webauthn 文件。如果该文件存在,浏览器会检查发出请求的来源是否在 allowlist 中。
如果是,则继续执行通行密钥创建或身份验证步骤。
如果浏览器不支持相关来源请求,则会抛出 SecurityError。
浏览器支持
Chrome 和 Safari 支持相关来源请求。截至 2026 年 1 月,Firefox 仍在考虑此功能。您可以在 Mozilla 标准立场问题 中跟踪其状态。
设置相关来源请求
以下演示使用了两个网站:https://ror-1.glitch.me 和 https://ror-2.glitch.me。
为了让用户能够使用同一通行密钥登录这两个网站,它使用相关来源请求允许 ror-2.glitch.me 将 ror-1.glitch.me 用作其 RP ID。
演示
https://ror-2.glitch.me 实现相关来源请求以将 ror-1.glitch.me 用作 RP ID,因此 ror-1 和 ror-2 在创建通行密钥或使用通行密钥进行身份验证时都使用 ror-1.glitch.me 作为 RP ID。
我们还在这些网站中实现了一个共享通行密钥数据库。
请注意以下用户体验:
- 您可以在
ror-2上成功创建通行密钥并使用通行密钥进行身份验证,即使其 RP ID 是ror-1(而不是ror-2)也是如此。 - 在
ror-1或ror-2上创建通行密钥后,您可以在ror-1和ror-2上使用该通行密钥进行身份验证。由于ror-2将ror-1指定为 RP ID,因此从任何这些网站发出通行密钥创建或身份验证请求与在 ror-1 上发出请求相同。RP ID 是将请求与来源关联的唯一因素。 - 在
ror-1或ror-2上创建通行密钥后,Chrome 会在ror-1和ror-2上自动填充该通行密钥。 - 在任何这些网站上创建的凭据的 RP ID 均为
ror-1。
请参阅代码:
第 1 步:实现共享账号数据库
如果您希望用户能够使用同一通行密钥登录 site-1 和 site-2,请实现一个在这两个网站之间共享的账号数据库。
第 2 步:在 site-1 中设置 .well-known/webauthn JSON 文件
首先,配置 site-1.com,使其允许 site-2.com 将其用作 RP ID。为此,请创建您的 webauthn JSON 文件:
{
"origins": [
"https://site-2.com"
]
}
JSON 对象必须包含名为 origins 的键,其值是一个或多个包含 Web 来源的字符串数组。
重要限制:最多 5 个标签
系统将处理此列表的每个元素,以提取 eTLD + 1 标签。
例如,example.co.uk 和 example.de 的 eTLD + 1 标签均为
example。但 example-rewards.com 的 eTLD + 1 标签为 example-rewards。
在 Chrome 中,标签数量上限为 5。
第 3 步:在 site-1 中提供 .well-known/webauthn JSON
然后,在 site-1.com/.well-known/webauthn 下提供 JSON 文件。
application/json该文件的正确格式为:/.well-known/webauthn(请勿添加 .json 扩展名)。
例如,在 express 中:
app.get("/.well-known/webauthn", (req, res) => {
const origins = {
origins: ["https://site-2.com"],
};
return res.json(origins);
});
在这里,我们使用的是 express res.json,它已设置
正确的 content-type ('application/json');
第 4 步:在 site-2 中指定 RP ID
在 site-2 代码库中,将 site-1.com 设置为所有需要的地方的 RP ID:
- 创建凭据时:
- 在传递给
navigator.credentials.create前端调用的凭据创建options中将site-1.com设置为 RP ID,这些options通常在服务器端生成。 - 在将
site-1.com设置为预期 RP ID 之前,请先运行凭据验证,然后再将其保存到数据库中。
- 在传递给
- 进行身份验证时:
- 在传递给
navigator.credentials.get前端调用的身份验证options中将site-1.com设置为 RP ID,这些options通常在服务器端生成。 - 在对用户进行身份验证之前,请先运行凭据验证,然后再将
site-1.com设置为要在服务器上验证的预期 RP ID。
- 在传递给
问题排查
其他注意事项
在网站和移动应用之间共享通行密钥
借助相关来源请求,您的用户可以在 多个网站 上重复使用通行密钥。 如需允许用户在 网站 和 移动应用 之间重复使用通行密钥, 请使用以下方法:
- 在 Chrome 中:Digital Asset Links。如需了解详情,请参阅 添加对 Digital Asset Links 的支持。
- 在 Safari 中: 关联的网域。
在网站之间共享密码
借助相关来源请求,您的用户可以在网站之间重复使用 通行密钥。 在网站之间共享 密码 的解决方案因密码管理器而异。 对于 Google 密码管理工具,请使用 Digital Asset Links 。Safari 有不同的系统。
凭据管理器和用户代理的角色
这超出了您作为网站开发者的范围,但请注意,从长远来看,RP ID 不应成为用户代理或用户使用的凭据管理器中用户可见的概念。相反,用户代理和凭据管理器应向用户显示凭据的 使用位置。此更改需要一段时间才能实现。临时解决方案是同时显示当前网站和原始注册网站。