密码是我们标准化的事物之一,因为我们已经使用它们多年了。用户会忘记它们、重复使用它们、将它们写在不该写的地方。团队必须管理重置、策略、哈希、泄漏、网络钓鱼和支持。
passkey 并没有使身份验证变得完美,但它们消除了一个巨大的问题:服务器不再需要保留与用户共享的秘密。
到底发生了什么
passkey是基于WebAuthn的凭证。当用户创建时,设备会生成一个密钥对:
- 私钥,保留在设备或密码管理器中;
- 服务器可以保存的公钥。
登录服务器时不会询问“告诉我密码”。发送随机挑战。设备使用私钥对其进行签名。服务器使用公钥验证签名。
这是很好的部分:如果数据库被盗,里面没有密码可以破解。如果用户最终进入假域名,则 passkey 对于该域名无效。这不仅仅是方便,更是针对网络钓鱼的具体保护。
浏览器充当桥梁
在浏览器中,两个主要的 API 是:
navigator.credentials.create()创建passkey;navigator.credentials.get()在登录时使用它。
但重要的逻辑是在服务器上。服务器必须生成质询,暂时保存,验证响应,检查源和Relying Party ID,然后创建会话。
客户端部分应该几乎很无聊:
const options = await fetch('/api/passkeys/login/options').then((r) => r.json()); const credential = await navigator.credentials.get({ publicKey: PublicKeyCredential.parseRequestOptionsFromJSON(options), }); await fetch('/api/passkeys/login/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(credential?.toJSON()), });
如果您发现自己手动实施WebAuthn加密,请停止。使用强大的服务器端库。这里的错误不是“可爱的错误”,它们是身份验证漏洞。
数据库中保存的内容
没有必要拯救半个世界。通常就足够了:
- 凭证的ID;
- 公钥;
- 连接的用户;
- 任何验证计数器或元数据;
- 传输(如果对用户体验有用的话);
- 用户选择的名称;
- 创建日期和最后使用。
最小的表可能如下所示:
create table passkey_credentials ( id uuid primary key default gen_random_uuid(), user_id uuid not null references users(id), credential_id text not null unique, public_key text not null, name text, created_at timestamptz not null default now(), last_used_at timestamptz );
然后我会添加审核日志和通知:如果有人在我的帐户上创建了新的passkey,我想知道它。
用户体验比演示更重要
passkey 的演示总是很漂亮:你点击,Face ID,你就进去了。实际产品更复杂。
有人换手机了有人使用锁定的公司计算机。有些人不明白为什么浏览器会建议passkey。有人失去了对其设备的访问权限。
这就是为什么我不会以“从今天起不再为每个人提供密码”开始。我会这样开始:
- passkey内部用户可选; 2.建议登录成功后创建一个; 3.账户页面重命名和删除passkey;
- 明确的后备方案; 5.在主登录中逐步推出。
界面中的文字应该简单。 “使用设备的锁定屏幕”比“使用居民 FIDO2 凭据进行身份验证”更好。
我会避免的错误
不要给客户带来挑战。质询是在服务器上创建的,并且只需验证一次。
不要只相信凭证 ID。您需要验证签名、质询、来源和Relying Party ID。
在拥有良好的恢复流程之前,请勿删除后备。无密码不一定要变成“如果你丢失了手机,你就永远出局”。
不要将 passkey 视为纯粹的前端按钮。隐藏按钮并不安全:真正的验证是在服务器端。
Passkey-优先还是passkey-友好?
对于新产品,您可以首先考虑passkey。对于现有的应用程序,我更喜欢passkey友好:添加passkey作为推荐方法,衡量成功和问题,然后冷静地减少密码权重。
感觉不到理想的迁移。用户发现登录变得更加容易,而不是公司改变了其身份验证协议。
结论
passkey 很有趣,因为它们同时提高了安全性和用户体验,这是罕见的。它们不是魔杖:恢复、兼容性、支持和推出仍有待精心设计。
但基本的变化是强烈的。停止要求用户发明和保护秘密。您让设备签署与您的域相关的加密证明。更少的人类记忆、更少的网络钓鱼、更少的密码重置。我想说它们值得认真对待。