在 Express.js 中构建身份验证系统的完整指南

阅读时长 14 分钟读完

身份验证是 web 应用程序中至关重要的一部分。在本文中,我们将通过使用 Express.js 构建一个完整的身份验证系统来深入探讨如何有效地实现身份验证。本文包含以下内容:

  • 什么是身份验证
  • 使用 Passport.js 实现身份验证
  • 实现注册和登录功能
  • 保护路由
  • 使用 JSON Web Tokens 进行令牌身份验证
  • 示例代码

什么是身份验证?

身份验证是确认用户是谁的过程。在 web 应用程序中,身份验证通常涉及用户提供凭据(例如用户名和密码),然后将这些凭据与存储在数据库中的用户信息进行比较。如果凭据匹配,用户就可以访问受保护的资源。否则,用户将被拒绝访问。

使用 Passport.js 实现身份验证

Passport.js 是一个流行的 Node.js 身份验证库,它提供了许多不同的身份验证策略,包括本地身份验证、OAuth、OpenID 等。在本文中,我们将使用本地身份验证策略。

要使用 Passport.js,您需要安装 passportpassport-local 包。您还需要安装 bcrypt 包来对用户密码进行哈希。

首先,我们需要配置 Passport.js。在您的应用程序的入口文件中,添加以下代码:

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

---------------- --------------
  ----- ------------------ --------- ----- -
    ----- ---- - ----- -------------- -------- ---
    -- ------- -
      ------ ---------- -------
    -
    ----- ------------- - ----- ------------------------ ---------------
    -- ---------------- -
      ------ ---------- -------
    -
    ------ ---------- ------
  -
---
展开代码

在这里,我们定义了一个本地身份验证策略。该策略接受用户名和密码,并使用 User.findOne() 方法在数据库中查找用户。如果找到了用户,则使用 bcrypt.compare() 方法比较密码是否匹配。如果密码匹配,则使用 done() 方法将用户对象传递给下一个处理程序。

接下来,我们需要为 Passport.js 配置序列化和反序列化功能。这些功能用于将用户对象序列化为一个字符串,以便将其存储在 session 中,并在需要时将其反序列化回用户对象。

在这里,我们使用 user.id 将用户对象序列化为字符串,并将其传递给 done() 方法。在反序列化功能中,我们使用 User.findById() 方法通过用户 ID 查找用户对象,并将其传递给 done() 方法。

最后,在您的应用程序中间件中添加以下代码以启用 Passport.js:

在这里,我们使用 express-session 中间件来启用会话。我们还使用 passport.initialize()passport.session() 中间件来启用 Passport.js。

实现注册和登录功能

现在我们已经配置了 Passport.js,让我们来实现注册和登录功能。首先,我们需要创建一个注册页面和一个登录页面。在这里,我们将使用 EJS 模板引擎来渲染这些页面。

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

---- ---- ---
----- ------------- ----------------
  ------ ----------- --------------- ------------------
  ------ --------------- --------------- -----------------
  ------ ------------- -----------
-------
展开代码

在这里,我们创建了一个注册表单和一个登录表单。这些表单将向 /register/login 路由提交数据。

接下来,让我们来实现 /register/login 路由。在这里,我们将使用 Passport.js 的 passport.authenticate() 方法来处理身份验证。

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

-- ----
------------------ ------------------------------ -
  ---------------- ----
  ---------------- --------
----
展开代码

在这里,我们使用 bcrypt.hash() 方法将用户密码哈希,并将其存储在数据库中。在注册完成后,我们使用 req.login() 方法将用户对象存储在会话中,并将用户重定向到主页。

在登录路由中,我们使用 passport.authenticate() 方法来处理身份验证。如果身份验证成功,则用户将重定向到主页。否则,用户将重定向到登录页面。

保护路由

现在,我们已经实现了注册和登录功能。让我们来看看如何保护受保护的路由。在这里,我们将使用 Passport.js 的 req.isAuthenticated() 方法来检查用户是否已通过身份验证。

在这里,我们检查用户是否已通过身份验证。如果用户已通过身份验证,则将用户对象传递给 profile 模板。否则,用户将被重定向到登录页面。

使用 JSON Web Tokens 进行令牌身份验证

使用 Passport.js 进行身份验证是一种流行的方法,但它并不是唯一的方法。另一种流行的方法是使用 JSON Web Tokens(JWT)进行令牌身份验证。

JWT 是一种用于安全通信的开放标准。它定义了一种用于在双方之间安全传输信息的方法。JWT 由三部分组成:头部、载荷和签名。头部和载荷是 JSON 对象,签名是使用密钥和头部和载荷的组合计算出来的值。

在身份验证过程中,服务器将生成一个 JWT 并将其发送给客户端。客户端将在每个请求中将 JWT 发送回服务器。服务器将验证 JWT 的签名,并使用载荷中的信息来确认用户的身份。

要使用 JWT 进行令牌身份验证,您需要安装 jsonwebtoken 包。接下来,让我们来看看如何生成和验证 JWT。

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

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

-- -- ---
----------------- --------- ----- -------- -- -
  -- ----- -
    -----------------
  - ---- -
    ---------------------
  -
---
展开代码

在这里,我们使用 jwt.sign() 方法生成 JWT。该方法接受一个载荷对象、一个密钥和一个选项对象。选项对象中的 expiresIn 属性指定 JWT 的有效期。

在验证 JWT 时,我们使用 jwt.verify() 方法。该方法接受一个 JWT、一个密钥和一个回调函数。如果 JWT 有效,则回调函数将传递解码的载荷对象。

要在 Express.js 中使用 JWT 进行令牌身份验证,您需要创建一个中间件函数。该函数将从请求头中提取 JWT,并验证其签名和有效性。如果 JWT 有效,则将用户对象添加到请求对象中。

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

-- ------
------------------- ------------------ ----- ---- -- -
  --------------------- - ----- -------- ---
---
展开代码

在这里,我们创建了一个名为 jwtAuthMiddleware 的中间件函数。该函数从请求头中提取 JWT,并使用 jwt.verify() 方法验证其签名和有效性。如果 JWT 有效,则将用户对象添加到请求对象中,并将请求传递给下一个处理程序。否则,将返回 401 或 403 错误。

示例代码

以下是完整的示例代码:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-- -----
---------------- -- -- -
  ----------------------
---
展开代码

在这里,我们使用 Express.js、Passport.js、bcrypt 和 JSON Web Tokens 来构建身份验证系统。我们实现了注册和登录功能,并保护了受保护的路由。我们还使用 JWT 来进行令牌身份验证。

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

纠错
反馈

纠错反馈