近年来,RESTful API 的使用越来越普遍,这种机制使得不同的系统之间可以相互交互,并实现数据的共享。但是,同时也带来了数据保密性和安全性的问题。为了解决这个问题,我们可以使用 JSON Web Tokens (JWTs) 和 Hapi.js 来保障 API 的安全性。
什么是 JSON Web Tokens (JWTs)
在深入了解 JWTs 之前,我们需要先了解一下什么是 token。在 Web 应用程序中,为了表示用户权限和识别用户数据,通常需要在用户登录后给出一个 token,然后把这个 token 附加到每个后来的请求中。在需要用户数据的地方,服务器可以根据这个 token 来验证用户的身份和权限。
JWTs 是另一种 token,但相比传统的 token,它们具有以下优点:
- 可以自包含所有的用户信息
- 可以签名、加密和解密
- 可以被用于安全的分布式系统认证
因此,除了在 web 应用程序中使用外,JWTs 在移动应用程序和 IoT 设备等地方也非常有用。
JSON Web Tokens(JWTs)是一种开放标准(RFC 7519),它定义了各个方面的声明在 JSON 格式中。这些信息可以被签名和/或加密后作为 token 传递,以确定其身份信息和所需访问的资源。
// JWT 示例 eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF 0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
使用 Hapi.js 和 JSON Web Tokens
下面我们将介绍如何使用 Hapi.js 和 JSON Web Tokens 来保护 API。
安装相关依赖
我们将使用 npm 包管理工具来安装必要的库。我们需要的依赖如下:
- hapi:Hapi 框架
- hapi-auth-jwt2:用于 JWT 身份验证
- jsonwebtoken:JWT 的生成实用程序
运行以下命令来安装上述依赖:
npm install --save hapi hapi-auth-jwt2 jsonwebtoken
实现 JWT 签名和验证
我们开始实现签名和验证 JWTs。首先创建一个名为 jwt.js
的文件来实现这个功能,代码实现如下:
-- -------------------- ---- ------- -- ------- ----- --- - ------------------------ ----- ------ - ---------------- -- ----------- -- -- ---- ------------------ - --------- -- - ----- ----- - ----------------- ------- - ---------- ---- --- -- ----- - - ------ ------ -- -- -- ---- ------------------- - ------- -- - --- - ----- ------- - ----------------- -------- ------ -------- - ----- ----- - ------ ------ - --
如上代码,我们首先引入了必要的库,然后定义了一个密钥(即 secret
)。在 issueToken
方法中,我们使用 jwt 包的 sign()
方法来生成基于输入数据(即 payload
)和密钥的 JWT。在这里,我们还为 JWT 指定了一个有效时间(expiresIn
)。否则,JWTs 将永远有效。
另一方面,在 verifyToken
方法中,我们使用 jwt 包的 verify()
方法来验证传入的 JWT。如果 JWT 有效,将返回解码的数据,否则将返回 false
。
创建一个 Hapi.js 服务器
下一步是创建一个 Hapi.js 服务器,并实现 JWT 的身份验证。下面是基本的启动文件 index.js
:
-- -------------------- ---- ------- -- ------- ----- ---- - ---------------- ----- --- - ----------------- -- ---- --- -------- -- -- ------- --- ----- ------ - --- ------------- ----- ---------------- -- ----- ------- - ----- - ------- ------ -- ---- - ------ ------------ ---- - - --- -- ---- ---- ----- ----- -------- - ----- --------- -------- -- -- - -- --------- - -- --------------- ------ - -------- ---- -- - ------ - -------- ----- -- -- -- -- --- -- ----- ---- - ----- -- -- - ----- ------------------------------------------- --------------------------- ------ - ---- ---------------- -- ----------- --------- -------------- - ----------- --------- -- --- --------------------------- -- ------- -- ---- -------------- ------- ------ ----- ---- -------- --------- -- -- - ------ ------ -------- -- ------- - ----- ----- - --- -------------- ------- ------ ----- ------------- -------- --------- -- -- - ------ ---- ----------- -- ------- - ----- ----- - --- -- ----- ------ -- -- - ----- --------------- ------------------- ------- --- --------------------- -----
如上代码,我们首先引入了必要的包和刚刚我们写的 JWT 签名和验证模块。然后我们创建了一个 Hapi.js 服务器,并通过调用 server.register()
方法来注册 hapi-auth-jwt2
插件。
下一步我们实现基于 JWT 的身份验证方式。使用 server.auth.strategy()
方法来定义我们的验证策略。在这里我们指定了密钥(yourSecretKey
)和解码验证选项(verifyOptions
)。我们还实现了一个 validate
方法来验证解码后的 JWT 是否有效。
最后,我们定义了两个路由,第一个不需要 JWT 验证,而第二个需要进行验证。如果 JWTs 验证通过,则返回 JWT protected
,否则返回 401 Unauthorized
。
测试
运行 node index.js
命令来启动本地服务器,访问 http://localhost:3000/
能够返回 hello world!
,而访问 http://localhost:3000/protected
则会返回 401 Unauthorized
。
下面我们通过 Postman 工具来测试有身份验证的 API:
- 先打开 Postman,然后在 Headers 中添加
Content-Type: application/json
和Authorization: Bearer <token>
。其中<token>
是我们使用生成 JWT 的签名代码生成的 token。 - 然后在 Postman 上点击 “Send” 按钮,我们就能够成功的访问到受到保护的 API 接口。
这里我们提供一个生成 JWT 的样例代码供参考:
const token = jwt.issueToken({ username: 'sang', role: 'admin' });
这将返回一个 JWT,可以将其附加到后续的请求中(作为 Authorization
头的值)来进行验证。
总结
JSON Web Tokens 具有自包含、可签名和可加密的优点,使其在分布式系统中的身份验证非常有用。本文介绍了如何使用 Hapi.js 和 JSON Web Tokens 实现基于 JWT 的身份验证。我们通过刚刚提到的 jwt.js
文件模块和测试用例,详细说明了如何签名和验证 JWT,同时也提供了一个完整示例代码供大家参考。在实际开发中,需要根据实际情况进行修改,比如密钥长度、过期时间等。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/653f3da07d4982a6eb8c528b