密码正在死亡:Passkey 无密码登录时代的前端实践

103 阅读15分钟

前言:一场认证方式的革命

2026年,密码正走向终结。

Google 停止了敏感操作的纯密码登录,Apple 将 Passkey 设为新 iCloud 账户的默认认证方式,GitHub 在每个登录页面都优先显示 Passkey 提示。全球三大科技巨头在短短几个月内达成共识:密码不再是安全的认证方式。

数据不会说谎:

  • 69% 的用户已经拥有至少一个 Passkey(2023 年仅 39%)
  • 48% 的全球前 100 网站已支持 Passkey
  • 93% 的登录成功率(传统密码仅 63%)
  • 87% 的企业已部署或正在部署 Passkey

对于前端开发者来说,这意味着什么?意味着我们需要从"表单 + 验证码校验"的传统模式,进化到"调用 WebAuthn API + 处理跨设备同步"的新时代。

本文将深入剖析 Passkey 的工作原理、前端接入方案、安全最佳实践,帮助你在这场认证革命中抢占先机。


一、什么是 Passkey

1.1 Passkey 是什么

Passkey(通行密钥)是一种基于 FIDO2/WebAuthn 标准的无密码认证方式。它使用公钥密码学,让用户通过生物识别(指纹、面容)或 PIN 码来验证身份,无需输入密码。

核心特性:

  • 防钓鱼:Passkey 与域名绑定,只能在注册时的域名下使用,无法在钓鱼网站上工作
  • 私钥永不离开设备:私钥存储在设备的安全区域(Secure Enclave/TPM),永远不会发送到服务端
  • 跨设备同步:通过 iCloud Keychain、Google Password Manager 或 Microsoft 账户自动同步
  • 无需记忆:告别密码管理的烦恼

1.2 为什么需要 Passkey

传统密码存在诸多问题:

易忘

普通人平均拥有 100+ 个在线账户,但只能记住 4-6 个密码。大多数人会重复使用密码或使用简单密码。

易猜

常见密码如 "123456"、"password" 仍被大量使用。黑客可以通过暴力破解轻易获取。

易钓鱼

钓鱼网站可以完美模仿正规网站,用户很难分辨。一旦输入密码,账户就会被盗。

易泄露

数据泄露事件频发,大量密码哈希被公开。即使使用了密码管理器,一旦主密码泄露,所有账户都会受到威胁。

1.3 Passkey 的发展历程

Passkey 的发展经历了三个阶段:

第一阶段:FIDO2/WebAuthn 标准制定(2019-2022)

2019 年,W3C 和 FIDO Alliance 联合发布了 WebAuthn 标准,为无密码认证奠定了基础。但此时浏览器支持不全,用户教育成本高,普及缓慢。

第二阶段:Passkey 概念诞生(2022-2024)

2022 年 5 月,Apple 在 WWDC 推出 iOS 16 的 Passkey 功能,基于 FIDO2 实现跨设备同步。2023 年 Google 跟进,2024 年 Microsoft 全面支持。

第三阶段:大规模普及(2025-2026)

到 2026 年,Passkey 已经成为主流认证方式。96% 的设备支持 Passkey,69% 的用户拥有至少一个 Passkey,48% 的顶级网站支持 Passkey 登录。


二、Passkey 工作原理

2.1 核心技术:公钥密码学

Passkey 基于公钥密码学(Public Key Cryptography),这是一种非对称加密技术。

公钥(Public Key)

  • 公开的密钥,存储在服务端
  • 用于验证签名的真实性
  • 可以自由分享,不会影响安全性

私钥(Private Key)

  • 保密的密钥,存储在设备的安全区域
  • 用于对挑战(Challenge)进行签名
  • 永远不会离开设备,即使设备丢失也无法被提取

数字签名(Digital Signature)

  • 私钥对挑战进行加密,生成签名
  • 服务端使用公钥验证签名的真实性
  • 如果签名有效,证明用户拥有对应的私钥

2.2 注册流程

第一步:用户注册账号

用户在网站上注册,输入邮箱或手机号。

第二步:设备生成密钥对

前端调用 navigator.credentials.create() API,设备生成一对公钥和私钥:

  • 私钥存储在设备的安全区域(如 Apple 的 Secure Enclave、Android 的 TPM)
  • 公钥发送到服务端

第三步:服务端存储公钥

服务端将公钥与用户账户关联,存储在数据库中。私钥永远不会离开设备。

2.3 认证流程

第一步:用户访问登录页

浏览器检测到网站支持 Passkey,自动显示可用的 Passkey 选项。

第二步:服务端发送挑战

服务端生成一个随机挑战(Challenge),并绑定当前域名。挑战是一个随机字符串,确保每次认证都是唯一的。

第三步:设备签名挑战

前端调用 navigator.credentials.get() API,设备使用私钥对挑战进行签名。签名前需要用户进行生物识别验证(指纹、面容或 PIN)。

第四步:服务端验证签名

服务端使用存储的公钥验证签名的真实性。如果签名有效,且域名绑定正确,则认证成功。

2.4 防钓鱼机制

Passkey 的防钓鱼能力是其最大的优势,核心在于域名绑定(Origin Binding)。

当设备生成 Passkey 时,会记录注册时的域名。在认证时,设备会检查当前域名是否与注册时的域名一致。如果不一致,设备会拒绝签名,即使私钥存在也无法使用。

这意味着:

  • 钓鱼网站无法使用用户在正规网站注册的 Passkey
  • 即使钓鱼网站模仿得再逼真,也无法通过 Passkey 认证
  • 用户无需担心被钓鱼攻击

三、认证流程对比

3.1 传统密码登录流程

传统密码登录需要以下步骤:

  1. 输入用户名:用户在登录表单中输入用户名或邮箱
  2. 输入密码:用户输入密码(可能需要回忆或查看密码管理器)
  3. 输入验证码:网站发送短信或邮箱验证码,用户输入
  4. 等待验证:服务端验证用户名、密码和验证码,返回结果

平均耗时:15-30 秒

问题:

  • 步骤繁琐,用户体验差
  • 密码易忘、易猜、易钓鱼
  • 验证码可能被劫持(SIM swapping)

3.2 Passkey 登录流程

Passkey 登录流程:

  1. 浏览器检测 Passkey:用户访问登录页,浏览器自动检测可用的 Passkey
  2. 生物识别验证:用户进行指纹、面容或 PIN 验证
  3. 自动完成登录:设备签名挑战,服务端验证,登录成功

平均耗时:2-3 秒

优势:

  • 步骤简洁,用户体验极佳
  • 无需记忆密码
  • 防钓鱼,安全性高
  • 登录成功率高达 93%

3.3 关键数据对比

指标传统密码Passkey
登录步骤4-5 步2-3 步
平均耗时15-30 秒2-3 秒
登录成功率63%93%
防钓鱼能力完全防钓鱼
密码泄露风险无(私钥不离开设备)
用户体验极佳

四、前端接入实战

4.1 准备工作

在开始接入 Passkey 之前,需要确保:

  1. HTTPS 环境:WebAuthn API 只能在 HTTPS 环境下使用(localhost 除外)
  2. 域名配置:确保域名正确,Passkey 与域名绑定
  3. 依赖库:选择合适的 WebAuthn 库,推荐使用 @simplewebauthn/browser

4.2 安装依赖

npm install @simplewebauthn/browser

或使用 Yarn:

yarn add @simplewebauthn/browser

4.3 注册 Passkey

让我们看一个完整的注册流程示例:

import { startRegistration } from '@simplewebauthn/browser';

async function handleRegister() {
  try {
    const options = await fetch('/api/webauthn/register/options', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username: 'user@example.com' }),
    }).then(res => res.json());

    const credential = await startRegistration(options);

    const verification = await fetch('/api/webauthn/register/verify', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ credential }),
    }).then(res => res.json());

    if (verification.verified) {
      console.log('Passkey 注册成功!');
    } else {
      throw new Error('注册验证失败');
    }
  } catch (error) {
    console.error('注册失败:', error);
  }
}

代码解析:

  1. 获取注册选项:前端向服务端请求注册选项,包括挑战(challenge)、用户信息等
  2. 开始注册:调用 startRegistration() API,设备生成密钥对
  3. 验证注册:将凭证发送到服务端,服务端验证并存储公钥

4.4 认证登录

import { startAuthentication } from '@simplewebauthn/browser';

async function handleLogin() {
  try {
    const options = await fetch('/api/webauthn/authenticate/options', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
    }).then(res => res.json());

    const assertion = await startAuthentication(options);

    const verification = await fetch('/api/webauthn/authenticate/verify', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ assertion }),
    }).then(res => res.json());

    if (verification.verified) {
      console.log('登录成功!');
      // 设置登录状态,跳转到首页
    } else {
      throw new Error('认证验证失败');
    }
  } catch (error) {
    console.error('登录失败:', error);
    // 回退到密码登录
  }
}

代码解析:

  1. 获取认证选项:前端向服务端请求认证选项,包括挑战(challenge)等
  2. 开始认证:调用 startAuthentication() API,设备使用私钥签名挑战
  3. 验证认证:将断言发送到服务端,服务端验证签名并确认登录

4.5 使用原生 API

如果你不想使用第三方库,也可以直接使用原生 WebAuthn API:

async function registerPasskey() {
  const publicKey = await fetch('/api/webauthn/register/challenge')
    .then(res => res.json());

  const credential = await navigator.credentials.create({ publicKey });

  await fetch('/api/webauthn/register', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(credential),
  });
}

async function authenticatePasskey() {
  const options = await fetch('/api/webauthn/auth/options')
    .then(res => res.json());

  options.mediation = 'conditional';

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

  const res = await fetch('/api/webauthn/auth', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(assertion),
  });

  if (res.ok) {
    console.log('登录成功');
  }
}

关键参数说明:

  • mediation: 'conditional':启用条件 UI,让 Passkey 像密码一样自动填充
  • publicKey.userVerification:控制是否强制用户验证(生物识别或 PIN)

4.6 推荐的库

根据项目需求,推荐以下库:

@simplewebauthn

  • 最流行的 WebAuthn 库
  • 提供完整的浏览器和服务端支持
  • 文档详细,社区活跃

Auth.js (NextAuth)

  • Next.js 项目首选
  • 内置 Passkey 支持
  • 支持多种认证方式

Lucia

  • 轻量级认证库
  • 支持 Passkey 和 OAuth
  • 适合需要自定义认证流程的项目

Clerk

  • 全托管认证服务
  • 一键集成 Passkey
  • 适合快速上线的项目

Supabase

  • BaaS 平台
  • 内置 Passkey 支持
  • 适合小型项目和原型

五、服务端实现要点

5.1 注册验证

服务端在验证注册时需要:

  1. 验证挑战:确保挑战是服务端生成的,且未被篡改
  2. 验证域名:确保注册时的域名与当前域名一致
  3. 存储公钥:将公钥与用户账户关联,存储在数据库中
  4. 生成凭证 ID:为每个 Passkey 生成唯一的凭证 ID

5.2 认证验证

服务端在验证认证时需要:

  1. 验证挑战:确保挑战是服务端生成的
  2. 验证签名:使用存储的公钥验证签名的真实性
  3. 验证域名:确保认证时的域名与注册时的域名一致
  4. 验证用户:确认凭证属于当前用户

5.3 数据库设计

推荐的数据库表结构:

CREATE TABLE passkeys (
  id UUID PRIMARY KEY,
  user_id UUID NOT NULL REFERENCES users(id),
  credential_id BYTEA NOT NULL UNIQUE,
  public_key BYTEA NOT NULL,
  device_name TEXT,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  last_used_at TIMESTAMP
);

字段说明:

  • user_id:关联的用户 ID
  • credential_id:凭证 ID,用于识别不同的 Passkey
  • public_key:公钥,用于验证签名
  • device_name:设备名称(可选)
  • created_at:创建时间
  • last_used_at:最后使用时间(用于清理长期未使用的 Passkey)

六、安全最佳实践

6.1 始终使用 HTTPS

WebAuthn API 只能在 HTTPS 环境下使用(localhost 除外)。确保生产环境使用 HTTPS,并配置 HSTS 头。

// Express.js 示例
app.use((req, res, next) => {
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  next();
});

6.2 验证域名绑定

服务端必须验证 Passkey 的域名绑定,防止跨域名攻击。

import { verifyRegistrationResponse } from '@simplewebauthn/server';

const verification = await verifyRegistrationResponse({
  credential,
  expectedChallenge: challenge,
  expectedOrigin: 'https://your-domain.com',
  expectedRPID: 'your-domain.com',
});

6.3 设置合理的用户验证级别

根据业务需求,设置合适的用户验证级别:

  • discouraged:不推荐用户验证(不建议用于敏感操作)
  • preferred:首选用户验证(如果设备支持)
  • required:强制用户验证(推荐用于敏感操作)
const options = {
  userVerification: 'preferred',
};

6.4 实现回退机制

虽然 Passkey 是未来的趋势,但仍有部分用户无法使用。需要提供回退机制:

  1. 密码登录:作为最后的回退选项
  2. 魔法链接:通过邮箱发送一次性登录链接
  3. TOTP 验证码:基于时间的一次性密码

6.5 定期清理未使用的 Passkey

定期清理长期未使用的 Passkey,减少安全风险:

// 删除 90 天未使用的 Passkey
const ninetyDaysAgo = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000);
await db.passkeys.deleteMany({
  where: { lastUsedAt: { lt: ninetyDaysAgo } },
});

6.6 实现多因素认证

对于敏感操作(如支付、账户设置),建议结合 Passkey 和其他因素:

  1. Passkey + 生物识别:已经内置在 Passkey 中
  2. Passkey + 设备绑定:验证登录设备是否为信任设备
  3. Passkey + 地理位置:验证登录位置是否为常用位置

七、常见问题与解决方案

7.1 用户没有 Passkey 怎么办

解决方案:

  • 在登录页面同时显示 Passkey 和密码登录选项
  • 如果用户没有 Passkey,自动回退到密码登录
  • 在注册页面引导用户创建 Passkey

7.2 Passkey 无法跨设备使用怎么办

解决方案:

  • Passkey 会自动通过 iCloud Keychain、Google Password Manager 或 Microsoft 账户同步
  • 如果用户更换设备,需要重新注册 Passkey
  • 建议用户在多个设备上注册 Passkey

7.3 设备丢失怎么办

解决方案:

  • 私钥存储在设备的安全区域,即使设备丢失也无法被提取
  • 用户可以在新设备上重新注册 Passkey
  • 建议用户启用设备查找和远程擦除功能

7.4 浏览器不支持 Passkey 怎么办

解决方案:

  • 检查浏览器兼容性,提供回退机制
  • 当前主流浏览器(Chrome 140+、Safari 16+、Firefox 120+)都支持 Passkey
  • 对于旧浏览器,使用密码登录作为回退

7.5 如何测试 Passkey

解决方案:

  • 使用 Chrome DevTools 的 WebAuthn 模拟器
  • 在 localhost 环境下测试(无需 HTTPS)
  • 使用真实设备测试生物识别功能

八、未来展望

8.1 Passkey 的普及趋势

根据当前数据,Passkey 的普及速度非常快:

  • 2023 年:39% 用户认知率
  • 2024 年:55% 用户拥有率
  • 2025 年:62% 用户拥有率
  • 2026 年:69% 用户拥有率

预计到 2028 年,Passkey 将成为主流认证方式,密码将逐渐退出历史舞台。

8.2 前端认证的演变

前端认证正在经历从"密码"到"无密码"的演变:

第一代:密码 + 验证码

  • 用户名 + 密码 + 短信/邮箱验证码
  • 安全性差,用户体验差

第二代:OAuth/SSO

  • 通过第三方平台登录(微信、支付宝、Google)
  • 安全性提升,但依赖第三方

第三代:Passkey

  • 基于公钥密码学的无密码认证
  • 安全性极高,用户体验极佳
  • 无需依赖第三方

8.3 对前端开发者的影响

Passkey 的普及对前端开发者有以下影响:

技能要求变化

  • 需要掌握 WebAuthn API
  • 需要理解公钥密码学基础
  • 需要了解跨设备同步机制

代码量减少

  • 无需实现复杂的密码验证逻辑
  • 无需处理密码重置流程
  • 无需实现验证码发送和验证

安全性提升

  • 减少密码泄露风险
  • 防钓鱼能力增强
  • 无需存储密码哈希

九、总结

9.1 核心要点

  1. Passkey 是未来:基于 FIDO2/WebAuthn 标准,防钓鱼、无需记忆密码
  2. 用户体验极佳:登录成功率 93%,平均耗时 2-3 秒
  3. 安全性高:私钥永不离开设备,域名绑定防钓鱼
  4. 接入简单:使用 @simplewebauthn 库,5 步搞定

9.2 行动建议

立即开始

  1. 在新项目中接入 Passkey
  2. 在现有项目中添加 Passkey 选项
  3. 为用户提供清晰的引导和说明

学习资源

9.3 最后的思考

密码的死亡不是突然发生的,而是一个渐进的过程。作为前端开发者,我们需要提前准备,拥抱无密码时代的到来。

Passkey 不仅仅是一种技术,更是一种理念:最好的密码,就是没有密码

让我们一起迎接这个更加安全、更加便捷的认证时代!


参考资料:

  1. WebAuthn 官方规范:www.w3.org/TR/webauthn…
  2. SimpleWebAuthn 文档:simplewebauthn.dev/
  3. FIDO Alliance:fidoalliance.org/
  4. Google Passkey 文档:developers.google.com/identity/pa…
  5. Apple Passkey 文档:developer.apple.com/documentati…
  6. State of Passkeys:state-of-passkeys.io/

📱 实用工具推荐

在日常工作和生活中,我们经常需要处理各种视频资源。如果你需要下载短视频平台上的视频,但又被烦人的水印困扰,那么这款小程序绝对值得一试!

三峋视频去水印

功能特点

  • 🎬 一键去水印:支持微信视频号、抖音、快手、小红书、B站等主流短视频平台,复制分享链接即可自动提取无水印视频
  • 🚀 极速下载:智能解析视频链接,秒级获取高清无水印视频
  • 💾 本地保存:下载的视频直接保存到手机相册,方便随时查看和当做素材使用或分享
  • 🆓 完全免费:所有功能永久免费使用,无解锁广告干扰,无隐藏收费

使用方法

  1. 在短视频平台找到喜欢的视频,点击分享按钮
  2. 复制视频的分享链接
  3. 打开「三峋视频去水印」小程序
  4. 粘贴链接,点击解析,即可获取无水印视频并下载

搜索方式

在微信小程序中搜索 「三峋视频去水印」,即可找到并使用这款实用工具!

无论是工作中需要提取视频素材,还是生活中想要保存喜欢的短视频,「三峋视频去水印」都能帮你轻松搞定,让去水印下载变得简单高效!