Hapi.js 中使用 JWT 实现身份认证的常见问题解决方案

阅读时长 13 分钟读完

JSON Web Tokens (JWT) 是一种用来传递认证信息的开放标准 (RFC 7519). 它可以通过加密和签名进行验证,并且可以在身份认证和授权过程中安全地传输信息。 在 Hapi.js 中实现 JWT 身份认证可以提供更高的安全性和更好的扩展性。

在本文中,我们将讨论使用 Hapi.js 和 JWT 实现身份认证时可能遇到的常见问题,以及如何解决这些问题,以及如何实现一个简单的 Hapi.js 应用程序,使用 JWT 进行身份验证。

JWT 基础

在 JWT 中,认证信息存储在 JSON 对象中,并使用一个密钥进行签名。签名允许应用程序验证请求的身份,并确保没有篡改过该信息。JWT可以通过将签名附加到消息中来发行,然后在访问路由时,可以通过验证签名来识别和验证请求。

以下是一个基本 JWT,由开发者指定:

JWT 由三个部分组成: 头部 (header)、载荷 (payload) 和签名 (signature)。

头部 (header)

头部包含有关令牌的元数据信息,如其类型(通常为 JWT)和所使用的加密算法。

alg 是用于签署JWT的算法,可以是HMAC SHA256,RSA等。typ表示令牌类型。

载荷 (payload)

载荷是JWT的有效数据和声明信息。载荷中包含有关用户的任何信息,以及应用程序所需的其他信息。作为一个约定,JWT载荷不加密,但是可以签名。

sub 是 JWT 的主题,name 是用户的名称,admin 是用户是否为管理员。

签名 (Signature)

JWT 使用密钥对组合的头部和载荷进行签名,以便验证它们是否完好无损,并以不可变的方式存储有关认证信息的所有信息。

签名通过将base64UrlEncode的header和payload串联起来,在其之间放置一个点 (.) 并使用密钥对其进行哈希运算获得。解析 JWT 时,验证密钥和哈希之间是否存在匹配的信息。

使用 Hapi.js 和 JWT 实现身份认证

现在,我们已经了解了 JWT 的基础知识,我们将开始使用 Hapi.js 来设置 JWT 身份验证。

安装相关依赖

要在 Hapi.js 中使用 JWT,您需要安装以下依赖项:

hapi是一个 Node.js 的 HTTP 框架,用于构建 Web 应用程序、 RESTful API、服务等,常常用来构建企业级 Web 框架。

joi 是一个用于自描述数据校验的 JavaScript 库,它令数据校验变得更加容易。

jsonwebtoken 是一个用于 JSON 查询和生成JWT的 JavaScript 库。

hapi-auth-jwt2 是一个 hapi.js 插件,它实现了 JWT 验证并自动获取和验证JWT(以及从jwt中提取信息)的方法。

准备工作

首先,我们需要在 Hapi.js 项目中添加身份验证插件 hapi-auth-jwt2,并为了演示方便,我们在实现本例之前可以新建一个文件夹,并初始化 hapi 项目:

接下来,使用以下命令安装 hapi-auth-jwt2:

然后,使用以下命令在当前工作目录下创建一个名为 index.js 的文件。

打开 index.js,然后添加以下代码:

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

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

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

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

------

这段代码创建并启动了 Hapi.js 服务器,它将侦听端口3000。如果打开 http://localhost:3000,您将看到回显信息。现在,我们将向服务器添加身份验证插件。

修改 index.js 的内容:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

------

代码中使用了一些新的库,让我们逐一说明。

HapiAuthJwt2

HapiAuthJwt2 是用于 JWT 验证的 hapi.js 插件。通过验证 JWT,可以使用此插件从请求中提取数据。

以下代码段初始化 JWT 身份验证插件。

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

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

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

首先,我们在 Hapi.js 服务器上注册了 HapiAuthJwt2 插件。然后,我们定义了一个 JWT 身份验证策略,并将其设置为默认身份验证策略。

我们为身份验证策略提供了以下信息:

  • 密钥:用于签名和验证令牌的密钥。
  • 验证:用来验证令牌。 validate 方法用于在验证令牌之前用传递 的荷载解码令牌。如果验证不成功,则验证响应中的错误包含一个简单的错误消息。 validateUser 是授予或拒绝访问令牌的函数。
  • 验证选项:有关 JWT 的验证选项。

Joi

使用 Joi 验证字段,确保客户端向服务器发送有效数据。这样可以防止对服务器执行恶意操作,以及在向数据库中写入数据之前对其进行验证,以提高其安全性。

在这个例子中,使用了一个简单的类似正则表达式的模式来匹配密码字符串。

payload 关键字用于检查请求有效负载中提供的对象是否有效,并且必须具有以下值:

  • email:必须是字符串,使用电子邮件模式进行验证。
  • password:必须是字符串,并使用模式进行验证。

这些规则确保有效负载是有效的,并提高了服务器的安全性。

Boom

在这个示例中,我们使用了 Boom 库,它是另一个 hapi.js 生态系统的库,用于关于错误的编程。

例如,我们可以通过返回 “Boom.unauthorized” 来实现错误的用户身份验证消息。

jsonwebtoken

jsonwebtoken 库用于创建和验证 JSON Web Tokens(JWTs)。

在此代码片段中,我们使用此库创建一个新 JWT 之前,增加可选的有效期为60分钟,这将添加到签名有效载荷中。

在上面代码的最后,服务器添加了两个路由。

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

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

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

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

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

/login

我们使用路由接收登录信息,并验证用户。在这里,我们检查该用户是否存在,然后检查密码是否与哈希值匹配。如果匹配,则生成JWT,否则返回错误消息。

/me

在这个小例子中,我们查看验证过程是否工作。我们想看到最终的JWT解码后的有效负载。

在以下输出中,对示例用户 John Doe 进行身份验证并获取JWT以供下一次请求使用。运行 node index.js 后,打开浏览器,并打开“http://localhost:3000/login”。为了展示出现错误,我们输入了一个不正确的密码和一个不存在的电子邮件地址。

结论

本文介绍了如何在 Hapi.js 应用程序中设置 JWT 身份验证。我们讨论了使用 Hapi.js 和 JWT 时可能遇到的常见问题,以及如何解决这些问题。我们深入了解了如何实施 Hapi.js 应用程序,使用 JWT 进行身份验证,并提供了代码片段来说明基本操作。

在实际生产环境中,可以使用官方推荐的方法实现身份认证,例如 OAuth2 和 OpenID Connect 等。JWT 仅是身份验证的一种补充手段。

希望本文能够帮助您解决一些身份认证中的问题,并为您提供有关使用 JWT 在 Hapi.js 中实施身份认证的清晰指导。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/672ef012eedcc8a97c8b8245

纠错
反馈