密码是账户安全中最薄弱的环节。它们可能被钓鱼、泄露、重复使用或遗忘。这就是我们添加 WebAuthn Passkeys 支持的原因 - 一种防钓鱼、无密码的认证方法,既更安全又更便捷。

什么是 Passkeys?

Passkeys 是存储在您设备(手机、笔记本电脑、安全密钥)上的加密凭证,用于替代密码进行认证。它们使用 WebAuthn 标准(FIDO2 的一部分),提供多项优势:

  • 防钓鱼 - Passkeys 绑定到网站域名,无法在假冒网站上使用
  • 没有可泄露的秘密 - 服务器上只存储公钥
  • 绑定设备 - 私钥永远不会离开您的设备
  • 生物识别保护 - 通常由 Face ID、Touch ID 或 Windows Hello 保护
  • 跨设备同步 - 现代平台通过 iCloud、Google 或 Microsoft 账户在设备间同步 Passkeys

我们的实现

我们将 WebAuthn Passkeys 支持集成到现有的 django-allauth 认证栈中,提供网页和移动端 API 端点。

注册流程

当用户注册新的 Passkey 时,流程如下:

  1. 客户端向服务器请求注册选项
  2. 服务器生成挑战,包含用户和依赖方信息
  3. 浏览器的 WebAuthn API 提示用户(生物识别或安全密钥)
  4. 客户端将凭证发送回服务器
  5. 服务器验证并存储公钥
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# API endpoint to begin registration
class WebAuthnRegistrationOptionsView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        from allauth.mfa.webauthn.internal import auth as webauthn_auth

        # Generate credential creation options
        creation_options = webauthn_auth.begin_registration(
            request.user,
            passwordless=False  # Use as 2FA, not passwordless
        )

        return Response({
            "success": True,
            "creation_options": creation_options,
        })

认证流程

使用 Passkey 进行双因素认证:

  1. 用户完成主要认证(用户名/密码或社交登录)
  2. 服务器返回挑战用于 WebAuthn 验证
  3. 浏览器请求 Passkey(生物识别触摸)
  4. 凭证与存储的公钥进行验证
  5. 用户完全通过认证
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class WebAuthnVerifyView(APIView):
    def post(self, request):
        credential = request.data.get("credential")

        # Complete authentication and verify credential
        authenticator = webauthn_auth.complete_authentication(
            request.user,
            credential
        )

        # Record usage for security monitoring
        authenticator.last_used_at = timezone.now()
        authenticator.save()

        return Response({"success": True})

Passkey 管理

用户可以管理已注册的 Passkeys:

  • 列出所有 Passkeys - 包含注册日期和最后使用时间
  • 重命名 Passkeys - 便于识别(例如,“iPhone”、“MacBook”)
  • 删除 Passkeys - 包含防止删除最后一个认证器的保护
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class WebAuthnListView(APIView):
    def get(self, request):
        authenticators = Authenticator.objects.filter(
            user=request.user,
            type=Authenticator.Type.WEBAUTHN
        ).order_by("-created_at")

        return Response({
            "passkeys": [
                {
                    "id": auth.pk,
                    "name": auth.wrap().name,
                    "created_at": auth.created_at.isoformat(),
                    "last_used_at": auth.last_used_at.isoformat() if auth.last_used_at else None,
                }
                for auth in authenticators
            ]
        })

API 端点

我们的 REST API 为移动应用提供完整的 WebAuthn 支持:

端点方法描述
/api/webauthn/register/options/GET获取注册挑战
/api/webauthn/register/complete/POST完成注册
/api/webauthn/authenticate/options/GET获取认证挑战
/api/webauthn/verify/POST验证 2FA 凭证
/api/webauthn/GET列出已注册的 Passkeys
/api/webauthn/<id>/PATCH重命名 Passkey
/api/webauthn/<id>/DELETE删除 Passkey

安全考虑

恢复码

当用户注册第一个认证器(Passkey 或 TOTP)时,我们会自动生成恢复码。这些一次性代码可在所有其他认证方法不可用时使用:

1
2
if Authenticator.objects.filter(user=request.user).count() == 1:
    auto_generate_recovery_codes(request._request)

防止锁定

如果删除最后一个 Passkey 会导致用户没有任何双因素认证方法,则不允许删除:

1
2
3
4
if not adapter.can_delete_authenticator(authenticator):
    return Response({
        "message": "Cannot delete - you must have at least one authentication method"
    }, status=400)

监控

我们通过 Datadog 指标跟踪 Passkey 使用情况以进行安全监控:

1
2
3
increment("webauthn.registration.success")
increment("webauthn.verify.success")
increment("webauthn.verify.failed")

浏览器支持

所有现代浏览器都支持 WebAuthn:

  • Chrome 67+
  • Firefox 60+
  • Safari 13+
  • Edge 79+
  • 移动端 Chrome、Safari、Firefox

对于旧版浏览器,用户仍可使用 TOTP(认证应用)或恢复码。

用户体验

添加 Passkey 只需几秒钟:

  1. 前往设置 → 安全 → 双因素认证
  2. 点击添加 Passkey
  3. 为您的设备命名(例如,“iPhone 15”)
  4. 使用 Face ID / Touch ID / Windows Hello 认证
  5. 完成!您的 Passkey 已注册

今后登录只需生物识别确认 - 无需输入密码或从认证应用复制代码。

为什么我们选择 Passkeys

方法钓鱼风险用户体验恢复方式
密码差(易忘、弱密码)邮件重置
SMS 2FA中(SIM 卡交换)一般手机号
TOTP 应用手动输入代码备份密钥
Passkeys非常低优秀恢复码

Passkeys 代表认证的未来。它们已被 Apple、Google 和 Microsoft 平台支持,几乎所有用户都可以使用。


准备好告别密码了吗?在您的安全设置中启用 Passkeys!