JSON Web Tokens (JWT) 是一种用于客户端和服务端之间安全传输信息的开放标准 (RFC 7519)。它使用 JSON 对象来在双方之间安全地传递声明信息,并且该对象是嵌入到一个签名的字符串中。在本文中,我们将会学习如何在 Deno 中使用 JWT 实现用户认证。
什么是 Deno?
Deno 是一个基于 TypeScript 和 V8 的 JavaScript/TypeScript 运行时环境,可以在安全的沙盒中运行 JavaScript 和 TypeScript。相比 Node.js,Deno 更加安全、现代化和高效,特别是在模块管理和安全方面有很大的改进。
引用依赖
在使用 JWT 实现用户认证之前,我们需要引入以下两个 Deno 模块:
- base64url
- jwt
我们可以使用以下命令将它们添加到我们的应用程序中:
import { encode } from "https://deno.land/std/encoding/base64url.ts" import { sign } from "https://deno.land/x/djwt/create.ts"
用户认证流程
在 JWT 中,用户认证流程分为以下几个步骤:
- 用户使用其用户名和密码登录
- 服务器验证用户的凭证是否正确
- 如果凭证正确,则根据该用户生成一个 JWT,并将其返回给客户端
- 客户端将 JWT 存储在本地,并在每个 HTTP 请求的 Authorization 标头中发送它
- 服务器使用 JWT 中的信息来验证客户端的请求是否合法
- 如果 JWT 有效,则服务器执行请求
生成和验证 JWT
以下是一个生成和验证 JWT 的示例代码:
-- -------------------- ---- ------- ------ - ------ - ---- --------------------------------------------- ------ - ----- ------ - ---- ------------------------------------ ----- ------ - ---------- ----- ------- - - ---- ------------- ----- ----- ----- -------- ---- - -- -- --- ----- --- - ----- ------ ------- -- ------- -- -- --- ----- ----------- - ----- ----------- -------
在这里,我们使用密钥 “mysecret” 来创建一个 JWT,并将它存储在变量 jwt 中。随后,我们使用密钥来验证 JWT,并将验证结果存储在变量 verifiedJwt 中。
JWT 的结构
一个 JWT 由三部分组成,它们使用点号 "." 分隔,包括:
- Header(头部):包含了 typ(类型) 和 alg(算法) 两个属性,分别用于指定 JWT 的类型和使用的签名算法
- Payload(载荷):包含了实际需要传递的信息 (例如用户 ID),并可以添加自定义的声明属性
- Signature(签名):使用密钥和 Header/Payload 中的信息生成,并用于验证 JWT 的有效性和完整性
例如下面是一个 JWT 长这个样子的:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNBZG1pbiI6dHJ1ZX0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
实现用户认证
下面是一个示例代码,演示了如何在 Deno 中使用 JWT 实现用户认证:
-- -------------------- ---- ------- ------ - ------ - ---- --------------------------------------------- ------ - ----- ------ - ---- ------------------------------------ ----- ------ - ---------- -- ------- ----- ----- - - - --- -- --------- -------- --------- ------- -- - --- -- --------- -------- --------- ------- -- - --- -- --------- -------- --------- ------- -- - -- ------ ----- -------- ---------------------- ------- --------- ------- - ----- ---- - ------------ -- ---------- --- -------- -- ---------- --- --------- -- ------- ------ ---- ------ - --- -------- --------- ------------- - - -- -- --- -- ----- -------- ----------------- ---- - ----- ------- - - ---- -------- ----- ------------- - ----- --- - ----- ------ ------- -- ------- ------ --- - -- -- --- -- ----- -------- ---------------- ------- - --- - ----- ----------- - ----- ----------- ------- ------ ------------------- - ----- ------- - ------ ---- - - -- -- --- ----- -------- -------------- ---- - -- -------------------------- - ----------------------- - --- --------------------- - - -------- -------- ----- ----- - ------ - ----- ---- - ----- ---------------------------- ----- ---- - ----- --------------------------- -------------- -- ------- - ----------------------- - --- --------------------- - - -------- -------- ----- ----- - ------ - ----- --- - ----- ----------------- ----------------------- - --- --------------------- - - -------- ------ ------------ ---- --- - - -- ------ --- ----- -------- ---------------- ---- - ----- --- - ------------------------------------------------------------- ----- -- ------ - ----------------------- - --- --------------------- - - -------- -------- ------------- ------ - ------ - ----- ------- - ----- ---------------- -- ---------- - ----------------------- - --- --------------------- - - -------- -------- ------------- ------ - ------ - ----------------------- - --- --------------------- - - -------- ----- ------- -------- ------- - -
在这个示例代码中,我们定义了三个函数:
- validateUser():用于验证登录凭证是否正确。如果是,则返回包含用户 ID 和用户名的对象;否则返回 null。
- generateJWT():用于根据用户信息生成一个 JWT,并将其返回。
- validateJWT():用于验证 JWT 是否有效。如果是,则返回一个包含 JWT Payload 中声明的信息的对象;否则返回 null。
随后,我们定义了两个 API:
- login():用于处理用户登录请求。如果凭证正确,则生成一个 JWT,并将其返回客户端。
- getUser():用于获取用户信息请求。如果 JWT 有效,则返回包含 JWT Payload 中声明的信息的对象;否则返回一个 HTTP 401 错误。注意,我们在它的前面提取并验证了 JWT。
如何使用本地存储保存 JWT
在实际生产中,我们很可能需要将 JWT 存储在客户端的本地存储中,以便在应用程序的不同部分中使用它。在浏览器环境中,我们可以将其存储在 localStorage 中,代码如下:
localStorage.setItem("myJwt", jwt) const storedJwt = localStorage.getItem("myJwt")
在 Deno 应用程序中,我们可以使用 Deno 的写入和读取文件系统函数来将其存储在本地文件中,并在需要时读取它:
await Deno.writeTextFile("myJwt.txt", jwt) const storedJwt = await Deno.readTextFile("myJwt.txt")
结论
在 Deno 中使用 JWT 实现用户认证是非常简单和安全的。我们只需要使用 Deno 模块中的 JWT 有关函数,实现一个 JWT 的基本逻辑,即可以完成用户认证流程。在实际开发中,应该根据实际应用场景,增强应用程序的稳定性和安全性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/671610e5ad1e889fe21a85a4