在 Deno 中使用 JSON Web Tokens 实现用户认证

JSON Web Tokens (JWT) 是一种用于客户端和服务端之间安全传输信息的开放标准 (RFC 7519)。它使用 JSON 对象来在双方之间安全地传递声明信息,并且该对象是嵌入到一个签名的字符串中。在本文中,我们将会学习如何在 Deno 中使用 JWT 实现用户认证。

什么是 Deno?

Deno 是一个基于 TypeScript 和 V8 的 JavaScript/TypeScript 运行时环境,可以在安全的沙盒中运行 JavaScript 和 TypeScript。相比 Node.js,Deno 更加安全、现代化和高效,特别是在模块管理和安全方面有很大的改进。

引用依赖

在使用 JWT 实现用户认证之前,我们需要引入以下两个 Deno 模块:

  • base64url
  • jwt

我们可以使用以下命令将它们添加到我们的应用程序中:

------ - ------ - ---- ---------------------------------------------
------ - ---- - ---- ------------------------------------

用户认证流程

在 JWT 中,用户认证流程分为以下几个步骤:

  1. 用户使用其用户名和密码登录
  2. 服务器验证用户的凭证是否正确
  3. 如果凭证正确,则根据该用户生成一个 JWT,并将其返回给客户端
  4. 客户端将 JWT 存储在本地,并在每个 HTTP 请求的 Authorization 标头中发送它
  5. 服务器使用 JWT 中的信息来验证客户端的请求是否合法
  6. 如果 JWT 有效,则服务器执行请求

生成和验证 JWT

以下是一个生成和验证 JWT 的示例代码:

------ - ------ - ---- ---------------------------------------------
------ - ----- ------ - ---- ------------------------------------

----- ------ - ----------
----- ------- - - ---- ------------- ----- ----- ----- -------- ---- -

-- -- ---
----- --- - ----- ------ ------- -- -------

-- -- ---
----- ----------- - ----- ----------- -------

在这里,我们使用密钥 “mysecret” 来创建一个 JWT,并将它存储在变量 jwt 中。随后,我们使用密钥来验证 JWT,并将验证结果存储在变量 verifiedJwt 中。

JWT 的结构

一个 JWT 由三部分组成,它们使用点号 "." 分隔,包括:

  1. Header(头部):包含了 typ(类型) 和 alg(算法) 两个属性,分别用于指定 JWT 的类型和使用的签名算法
  2. Payload(载荷):包含了实际需要传递的信息 (例如用户 ID),并可以添加自定义的声明属性
  3. Signature(签名):使用密钥和 Header/Payload 中的信息生成,并用于验证 JWT 的有效性和完整性

例如下面是一个 JWT 长这个样子的:

--------------------------------------------------------------------------------------------------------------------------------------------------------

实现用户认证

下面是一个示例代码,演示了如何在 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 中,代码如下:

----------------------------- ----
----- --------- - -----------------------------

在 Deno 应用程序中,我们可以使用 Deno 的写入和读取文件系统函数来将其存储在本地文件中,并在需要时读取它:

----- ------------------------------- ----
----- --------- - ----- ------------------------------

结论

在 Deno 中使用 JWT 实现用户认证是非常简单和安全的。我们只需要使用 Deno 模块中的 JWT 有关函数,实现一个 JWT 的基本逻辑,即可以完成用户认证流程。在实际开发中,应该根据实际应用场景,增强应用程序的稳定性和安全性。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/671610e5ad1e889fe21a85a4