开发者指南:手把手实现Passkeys无密码认证

本文详细介绍了如何从零开始实现基于公钥加密的Passkeys无密码认证系统,涵盖服务端与客户端配置,并演示如何使用Descope可视化工具快速集成免代码认证流程,提升安全性和用户体验。

开发者指南:如何实现Passkeys

本指南详细讲解开发者如何集成基于Passkeys的无密码认证来增强安全性和用户体验。内容包括手动实现Passkeys的服务端和客户端设置,同时展示Descope如何通过可视化界面和预构建流程简化这一过程。

本文作者Kumar Harsh是来自印度的软件开发者和技术作者。您可以访问他的网站查看更多作品!

将Passkeys集成到应用程序的认证流程中可以显著提升安全性和用户便利性。本开发者指南全面概述了实现Passkeys所需的步骤,从初始设置到最终部署。遵循这些指南,您可以为用户创建无缝且安全的认证体验,降低未授权访问风险,增强对应用程序的整体信任。

Passkey认证简介

与容易受到暴力攻击和网络钓鱼的密码不同,Passkeys利用公钥加密技术来改善用户体验和安全性。想象一个保险库,您的身份被锁在里面,只有通过唯一的密钥对才能访问。Passkeys的工作原理类似,每个用户拥有一个私钥(主密钥安全保存在设备上)和一个与网站共享的公钥。

登录时,网站向用户设备发送一个挑战(数字谜题)。私钥随后创建唯一的签名(数字指纹),证明您的身份而不泄露实际密钥。这确保了即使网站被攻破,您的登录仍然安全。

以下示意图帮助您更好地理解这一过程: ![Passkey认证流程示意图]

如何实现Passkeys

虽然Passkeys的概念听起来很令人兴奋,但从头开始实现相当复杂。本节将学习如何从头开始实现Passkey认证,然后了解Descope如何简化这一过程。

在不使用第三方库的情况下在应用中实现Passkeys在技术上是可行的。但由于设置的复杂性和涉及的安全风险,强烈不建议这样做。最好选择支持的库之一,并按照其文档在应用中实现Passkeys。

通常,实现需要完成以下步骤:

服务端设置:需要在服务器上实现密钥生成、签名验证和认证处理。还需要集成数据库或用户管理系统来存储和检索用户信息及Passkey凭据。

前端集成:服务器设置完成后,可以使用JavaScript的navigator.credentials.create()navigator.credentials.get()方法在客户端启动注册和认证流程。客户端需要引导用户与其认证设备交互(如指纹扫描、PIN输入和其他设备),并将注册和认证数据发送到服务器进行处理。

最好使用可信库(如SimpleWebAuthn)来简化此过程。该库负责为您实现密钥生成和处理,使过程比从头开始简单得多。

如果您有兴趣了解如何使用SimpleWebAuthn在项目中从头开始实现Passkeys,可以查看此示例项目。该项目包含基于React的客户端和基于Node.js + Express的服务器。

服务端设置

服务器使用@simple-webauthn/server包暴露四个重要端点:

  • /generate-registration-options:此端点配置并生成客户端的可用注册选项列表。它使用当前登录用户的详细信息来确保同一设备不会多次注册。它还生成并发送挑战,客户端可用其注册新设备。
  • /verify-registration:此端点验证设备上注册是否成功。验证成功后,用户的注册详细信息(公钥、凭据ID和设备信息)将保存在数据库中。
  • /generate-authentication-options:此端点返回用户的可用认证选项。服务器在此步骤中查找设备表,并检索用户注册设备的设备ID,以允许通过该设备进行认证。
  • /verify-authentication:此端点用于验证设备上认证是否成功。它还验证是否使用了注册设备进行认证。

此服务器实现假设您已执行简单的初始认证以识别用户,并收集其内部ID(如UUID)来触发注册和认证流程。在实际场景中,您需要自己实现此步骤,并将用户ID插入代码中的loggedInUserId变量。

另请注意,此实现当前不包括与数据库集成以存储和检索用户凭据。这是您考虑将其投入生产时需要处理的另一项任务。添加用户认证数据库还需要额外的维护。

客户端设置

此方法的客户端实现相对简单。需要设置两个按钮:一个用于触发Passkeys注册,另一个用于触发认证。

onRegistrationStart事件中,需要向/generate-registration-options端点发出请求,首先从后端获取认证配置。然后使用这些选项,通过@simple-webauthn/browser包中的startRegistration()函数在前端启动注册仪式。

一旦从startRegistration()调用获得成功响应(即设备上的Passkey生成成功完成),然后向/verify-registration端点发出请求,使用startRegistration()调用返回的响应验证注册是否成功。服务器验证注册结果,并在成功注册后将设备详细信息存储在数据库中。

认证时逻辑类似。向/generate-authentication-options端点发出请求,并使用后端服务器返回的响应调用@simple-webauthn/browser包中的startAuthentication()方法。这会启动用户的设备上验证并生成中间响应。然后将此响应发送到/verify-authentication端点以完成认证过程并授予用户对应用程序的访问权限。

如您所见,此方法相当复杂,需要额外的设置和维护来进行用户识别和认证数据存储。此外,如果您希望通过HTTPS部署此功能,需要遵循SimpleWebAuthn文档中概述的额外步骤以确保安全。

现在让我们看看如何使用Descope简化Passkey实现,省去这些麻烦。

使用Descope更简单地实现Passkeys

与其从头开始设置Passkeys,甚至费心学习专用的第三方Passkeys库如何工作,不如使用像Descope这样的解决方案,它可以通过简化的无代码界面帮助您实现Passkeys以及其他认证模式。

创建Descope流程

要尝试,请访问Descope网站并注册永久免费账户。获得开发者仪表板访问权限后,可以开始创建认证流程。点击左侧导航面板中的"Getting Started":

![Descope入门向导]

点击"Consumers"开始为面向用户的应用程序构建认证流程。然后点击右下角的蓝色"Next"按钮。

在下一个屏幕上,选择"Passkeys (WebAuthn)“作为主要认证方法,并点击蓝色"Next"按钮:

![选择Passkeys作为主要认证方法]

在下一个屏幕上,可以选择其他认证方法作为2FA流程的一部分:

![选择2FA方法]

可以通过点击右下角的"Go ahead without MFA"按钮跳过此步骤。然后需要选择登录屏幕,可能包括额外的注册方法,允许用户注册并在其设备上设置Passkeys,然后才能开始使用:

![选择登录屏幕]

在此步骤中随意选择任何登录屏幕。最后,点击"Next"按钮预览您的选择。如果一切看起来都正确,点击"Next"按钮。Descope现在将创建您的认证流程,并提供示例代码片段以开始使用:

![在应用中集成Descope]

代码片段包含您的项目ID。只需要项目ID来配置Descope客户端或服务器SDK,以在应用中使用您的认证流程。

设置React项目

要尝试Descope流程,通过运行以下命令在本地创建新的React项目:

1
npm create vite

选择React作为框架,选择JavaScript作为语言,并为项目命名(例如passkeys-descope)。

项目准备就绪后,通过运行以下命令安装React Descope SDK:

1
npm install @descope/react-sdk

这就是您需要的所有设置。现在可以开始编写集成认证流程的代码。

需要对两个文件进行更改以将Descope集成到项目中。首先,需要在main.jsx文件中设置Descope AuthProvider,以允许在整个应用中访问认证逻辑。为此,将main.js中的代码替换为以下内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { AuthProvider } from '@descope/react-sdk';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
        <AuthProvider
            projectId='<your-project-id>'
        >
            <App />
        </AuthProvider>
    </React.StrictMode>
);

现在可以使用Descope组件和钩子按需在应用中设置认证。以下是一个简单的示例实现,可用于尝试应用中的Passkeys认证流程:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// 将App.js的内容替换为以下代码

import { useCallback } from 'react'
import { useDescope, useSession, useUser } from '@descope/react-sdk'
import { Descope } from '@descope/react-sdk'

const App = () => {
  const { isAuthenticated, isSessionLoading } = useSession()
  const { isUserLoading } = useUser()
  const { logout } = useDescope()

  const handleLogout = useCallback(() => {
    logout()
  }, [logout])

  return <>
    {!isAuthenticated &&
      (<div style={{display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", height: "100vh"}}>
        <div style={{ maxWidth: "500px" }}>
          <Descope
            flowId="sign-up-or-in"
            onSuccess={(e) => console.log(e.detail.user)}
            onError={(e) => console.log('Could not log in!')}
          />
        </div>
      </div>
      )
    }

    {
      (isSessionLoading || isUserLoading) && <p>Loading...</p>
    }

    {!isUserLoading && isAuthenticated &&
      (
        <>
          <p>Logged in!</p>
          <button onClick={handleLogout}>Logout</button>
        </>
      )
    }
  </>;
}

export default App;

就是这样!现在可以尝试使用Passkeys的认证流程。

尝试应用

要尝试应用,运行以下命令:

1
npm run dev

访问http://localhost:5173查看应用。注册时,需要使用社交流程或任何其他流程注册新用户并在其设备上设置Passkey。根据偏好点击"Continue with Google"或"Continue with Microsoft"并选择账户。

完成后,系统将要求提供其他详细信息(如姓名)作为注册过程的一部分:

![提供额外账户详细信息]

接下来,系统将询问是否要为此账户设置Passkeys:

![选择加入Passkeys]

点击蓝色的"Add passkeys"按钮。Chrome将要求确认创建Passkey:

![Chrome的Passkey对话框]

点击"Continue"后,系统将要求通过设备登录(如生物识别Touch ID或设备PIN(如果已设置))验证身份:

![用户验证]

验证账户后,Passkeys将设置完成,您将登录:

![已登录]

现在可以尝试使用Passkeys登录。为此,点击"Logout"按钮,并在Passkeys输入框中输入用户ID(本例中为电子邮件):

![使用Passkeys登录]

点击"Sign in with Passkeys"按钮后,系统将要求验证设备上的身份以访问本地存储的Passkeys:

![设备上验证]

验证身份后,您将直接登录,无需输入任何应用特定密码或PIN!

此外,还可以启用Passkeys自动填充,为用户提供更好的登录体验。为此,在Descope仪表板中导航到"Sign Up or In"流程,并转到"Welcome Screen"页面:

![启用Passkey自动填充]

在此页面的右窗格中切换"Enable sign in with Passkey Autofill”,并点击右上角的"Done > Save"。这将在Passkey输入框中启用自动填充选项。要测试,导航到登录屏幕并点击Passkey输入框。应该看到类似以下的自动填充列表:

![Passkeys的自动填充选项]

可以在GitHub仓库中找到本教程构建的完整代码。

使用Descope拖放式Passkey认证

Descope简化了在应用中实现Passkeys的过程,消除了手动设置复杂客户端和服务器端认证逻辑的需要。它提供可视化工作流,用于管理面向用户的屏幕以进行渐进式分析、后端认证逻辑以及跨不同认证方法的用户身份合并。

![使用Descope拖放式Passkey认证]

这种方法不仅使入门变得简单,还简化了随时间修改用户旅程的过程。

Descope提供直观的工具和清晰的说明,使所有技能水平的开发者都能将安全、无缝的登录流程集成到他们的应用中。借助拖放功能,即使是初学者也可以轻松实现认证流程,为用户提供更快、更简单、更易访问的登录。

通过注册永久免费账户来查看Descope。如果有问题,可以与Descope认证专家预约时间了解更多信息。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计