Skip to content

结论速览

可以,但要满足其一

  1. 同账号同步:公司电脑上的 Chrome/Edge 登录的是同一个 Google 账号 A(且允许密码管理器/数据同步)→ 该通行密钥会通过 Google Password Manager 同步过来,直接可用。(Google 帮助)
  2. 跨设备(Hybrid/手机扫码):即使公司电脑登录的是 Google 账号 B、本机没有那把密钥,也仍可用手机上的那把密钥(Android 的 Google Password Manager 或 iPhone 的 iCloud Keychain)扫码/Bluetooth 完成登录——前提是后端/前端允许 hybrid 传输。(FIDO Alliance)

反之,如被企业策略禁用密码管理器/蓝牙/Passkeys,或你把 allowCredentials 限得过死且没启用 hybrid,就可能失败。(chromeenterprise.google)

为什么“不同账号”也能登录(在手机在场时)

  • 跨设备登录机制(Hybrid/caBLE):桌面浏览器在没有本机凭据时会展示 二维码/附近设备 流程,手机扫描后通过 BLE 近距校验 与端到端加密信道完成签名;这不要求桌面与手机是同一个 Google 账号,只要手机里有那把通行密钥即可。(FIDO Alliance)
  • 苹果官方也支持“非 Apple 设备用 iPhone 的 Passkey”:在 Windows/Chrome 上选择“其他方式/来自附近设备”,显示二维码,用 iPhone 扫码 + Face/Touch ID 即可。(Apple 支持)

你这次能不能“直接成功”?看这三件事

  1. 前端是否把 hybrid 加进 allowCredentials[*].transports(没有就很难触发手机扫码)。(MDN Web Docs)

  2. 是否采用了“可发现凭据”的正确姿势

    • 场景 A(已知用户):给出该用户的全部 credentialId 列表;
    • 场景 B(账号发现/一键直登)省略 allowCredentials(传空数组),让浏览器列出本机/手机上此 RP 可用的 passkeys。(web.dev)
  3. 现场环境:电脑与手机 蓝牙可用、企业策略未禁用密码管理器/Passkeys/蓝牙等。(chromeenterprise.google)

提醒:当你指定了 allowCredentials 时,浏览器只能用到列表里存在的那几个 credentialId;若当前设备(包括通过手机走 hybrid)没有完全匹配的那个 ID,就会匹配失败。要覆盖更多情况,可把该用户已绑定的所有 ID 都给出,或在需要“账号发现”时传空数组。(MDN Web Docs)

开发落地要点(最小改动)

你之前的代码基本已经具备能力,这里只强调关键两处“容易踩坑”的地方(只给改动点):

ts
// 复杂逻辑:构建 allowCredentials 时一定带上 hybrid,让桌面可用“用手机的通行密钥”
const transports: AuthenticatorTransport[] = [
  "hybrid",
  "internal",
  "usb",
  "nfc",
  "ble",
];

(依据:PublicKeyCredentialRequestOptions.allowCredentials[].transports 支持 "hybrid";建议把注册时的 getTransports() 存起来用于后续请求。(MDN Web Docs))

ts
// 复杂逻辑:兜底为“账号发现/条件式 UI”——当精确匹配失败时,传空的 allowCredentials
await navigator.credentials.get({
  publicKey: {
    challenge,
    allowCredentials: [], // ← 让浏览器/系统列出该 RP 可发现的 passkeys(含手机扫码)
    userVerification: "preferred",
  },
  // 支持时启用 Conditional UI(表单自动填充)
  mediation: await(
    PublicKeyCredential as any
  ).isConditionalMediationAvailable?.()
    ? "conditional"
    : undefined,
});

(依据:Discoverable credentials 场景下推荐省略 allowCredentials,由浏览器列出可用 passkeys。(web.dev))


具体到你的问题:公司电脑(Google 账号 B)是否“支持”?

  • 支持(方式一):把公司电脑切换/新增到 Google 账号 A,并开启 Google Password Manager 同步 → 通行密钥会同步到该电脑,无需手机即可登录。(Google 帮助)
  • 支持(方式二):保持 账号 B 不变,但手机在身边且前端允许 hybrid → 桌面以 二维码/附近设备 方式调用手机上的通行密钥完成登录。(FIDO Alliance)
  • 可能不支持:被企业策略禁用(密码管理器/蓝牙/Passkeys)、或你的实现allowCredentials 限死且当前设备/手机找不到匹配的 credentialId。(chromeenterprise.google)

参考

  • Discoverable/省略 allowCredentials:web.dev 深入指南。(web.dev)
  • Google Password Manager 同步机制:Google 支持 & 开发者文档。(Google 帮助)
  • 跨设备(Hybrid/QR+BLE):FIDO Alliance 概述、Chrome/开发者说明、苹果支持“在非 Apple 设备上用 iPhone 的 Passkey”。(FIDO Alliance)
  • transports 包含 hybrid:MDN & 规范。(MDN Web Docs)
  • 企业策略可能限制:Chrome/Edge 企业策略文档。(chromeenterprise.google)

一句话落地:要么同账号同步,要么启用 hybrid 走“手机在身边”的跨设备登录;实现上别忘了 transports: ['hybrid', ...],必要时在兜底流程里allowCredentials 置空**以启用“账号发现”。

本站总访问