在 Web 应用开发中,用户认证是一个必不可少的部分。JWT(JSON Web Token)是一种经典的 Web 认证方案,它使用 JSON 对象作为令牌(token)并使用数字签名保证其安全性。在本文中,我们将介绍如何使用 Hapi 框架搭建一个基于 JWT 的用户认证系统。
Hapi 简介
Hapi.js 是一个 Node.js Web 应用框架,由 Walmart Labs 开发。通过使用 Hapi,我们可以快速搭建起一个可靠、安全、可扩展的 Web 应用。Hapi 具有以下特点:
- 轻量级:Hapi 基于 Node.js,是一个轻量级的 Web 应用框架。
- 插件化:Hapi 在设计上非常注重模块化和可重用性。我们可以通过使用插件来扩展 Hapi 的功能。
- 安全性:Hapi 提供了许多工具和调试支持,可以帮助我们避免一些常见的安全漏洞。
- 可测试性:Hapi 提供了一系列测试和 mock 工具,可以帮助我们方便地编写和运行测试。
JWT 简介
JWT 是一种用于对 Web 应用进行认证和授权的标准。JWT 令牌(token)由三部分组成:
- Header:存储了令牌的类型(即 JWT)以及所使用的算法(比如 HMAC SHA256 或 RSA)等信息。
- Payload:包含了个人的一些信息,比如用户名、用户 ID、角色等。
- Signature:由上文提到的 Header 和 Payload 以及一个密钥组成的数字签名,确保了令牌的完整性和真实性。
由于使用了数字签名,因此 JWT 令牌是安全可靠的,并且回避了传统的基于会话(Session)的认证方式所面临的一些问题。
搭建基于 Hapi 和 JWT 的用户认证系统
在本文中,我们将使用 Hapi 和 JWT 来搭建一个用户认证系统。我们将实现以下功能:
- 用户注册和登录;
- JWT 令牌生成、验证和刷新;
- 后端路由进行用户认证;
- 登出功能。
安装 Hapi 和 JWT
首先,我们需要安装如下两个 npm 包:
npm install hapi jsonwebtoken
编写用户认证系统
注册和登录
我们首先编写用户注册和登录的 API 接口。具体代码如下所示,使用了 Hapi 的路由插件来定义路由:
-- -------------------- ---- ------- ---- -------- ----- ---- - ---------------------- ----- --- - --------------------- ----- --- - ------------------------ ----- ------ - ------------- ----- ----- ----- ----------- --- ----- ----- - --- -- ------ --- -------------- ------- ------- ----- --------- -------- --------- -- -- - ----- ---- - ---------------- ----------------- ------ - -------- ----- ------- ------------- -- -- -------- - --------- - -------- ------------ ------ -------------------------------- --------- ------------------------------ -- - - --- -- ------ --- -------------- ------- ------- ----- --------- -------- --------- -- -- - ----- - ------ -------- - - ---------------- ----- ---- - ------------ -- ------- --- ----- -- ---------- --- ---------- -- ------- - ------ - -------- -------- ----- -- --------- -- - ----- ----- - ---------- ---- ------- -- ---------------- - ---------- ----- --- ------ - ----- -- -- -------- - --------- - -------- ------------ ------ -------------------------------- --------- ------------------------------ -- - - --- ----- -------- ------- - --- - ----- --------------- ------------------- ------- -- ---- ----------------- - ----- ----- - ----------------- ---------------- - -- --------
在上面的代码中,我们定义了两个路由,一个用于用户注册,另一个用于用户登录。在用户注册时,我们通过判断 email 和 password 是否合法来验证用户的输入。对于用户登录,我们查找是否有匹配的 email 和 password 组合,如果存在合法的用户则生成一个 JWT 令牌并返回给客户端。在实际使用中,需要将 'my_secret_key' 跟换成一个更加安全的密钥。
JWT 鉴权
接下来,我们将编写一个 Hapi 插件来进行 JWT 鉴权。具体代码如下所示:
-- -------------------- ---- ------- ---- -------- ----- --- - ------------------------ ----- -------- - ----- --------- -------- -- -- - -- ------------------------ ------ - -------- ---- -- -- -------------- - - ---- -------------------------- --------- -------- -------- -- - ----- - ------ - - -------- --------------------------- ------ - ---- ------- --------- -------------- - ----------- --------- - --- - --
在上面的代码中,我们编写了一个 Hapi 插件来进行 JWT 鉴权。在插件中,我们通过 validate
函数来对 JWT 令牌进行验证。在实际使用中,我们可以在 validate
函数中对用户的身份进行验证,比如从数据库中查询相关信息。在验证成功后我们返回 { isValid: true }
,否则返回 { isValid: false }
。
我们使用 server.auth.strategy('jwt', 'jwt', ...)
语句建立了一个名为 jwt
的认证策略。在这里,我们指定了一个密钥 secret
,提供了进行 JWT 鉴权所需的所有信息,包括密钥、验证函数和验证算法等。
路由认证
最后,我们将使用 JWT 认证插件来对受保护的路由进行认证。具体代码如下所示:
-- -------------------- ---- ------- ---- -------- ----- ---- - ---------------------- ----- --------------- - ------------------------------ ----- ------ - ------------- ----- ----- ----- ----------- --- -- -- --- ---- ----- ----------------- ------- ---------------- -------- - ------- --------------- - --- -- ------ -------------- ------- ------ ----- ----------- -------- --------- -- -- - ------ - -------- -------- -- ---- -------- -- -- -------- - ----- ----- - ---
在上面的代码中,我们使用 server.register
方法将 JWT 认证插件引入到我们的应用中,并通过设定 options
参数来传递我们预设的密钥 my_secret_key
。在路由定义中,我们指定了某些特定路由需要进行 JWT 认证,通过 options.auth
来指定应用的认证策略函数名称。
总结
在本文中,我们使用 Hapi 和 JWT 搭建了一个用户认证系统,并实现了用户的注册和登录、JWT 令牌的生成和验证等功能。Hapi 是一个功能强大的 Node.js Web 应用框架,拥有强大的插件系统并易于使用。通过使用 JWT 来完成用户认证,我们可以得到一个更加灵活和安全的解决方案。
示例代码
完整的示例代码可以在 GitHub 中找到。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64d21f89b5eee0b52597f446