在 MEAN 栈中为保护路由添加中间件

17 Mar 2025 | 6 分钟阅读

在我们上一节中,我们成功获取了我们的 Web 令牌。在本节中,我们将把这个 Web 令牌发送回我们的客户端。我们可以在 Angular 应用中接收它。我们将使用该令牌来控制后端访问,并拒绝任何没有有效令牌的请求。然后,我们将通过将令牌添加到 Angular 发送到这些受保护端点的请求中,来仍然可以访问这些请求。我们将按照以下步骤进行操作。

我们首先在服务器端验证令牌。因此,我们检查传入请求是否附加了有效令牌。我们将对我们的一些路由执行此操作。但是问题是哪些路由应该被保护?在后端,用户相关的登录和注册路由不应该被保护。我们网页的任何用户都应该能够访问这些路由。任何用户都应该能够向这些路由发送请求,因为对注册和登录感兴趣的用户未经验证。

现在对于帖子,我们有一些路由应该被保护,例如,用于创建新帖子的 post 路由,或用于编辑帖子的 put 路由,以及 delete 路由也应该对未经验证的用户禁用。所以,我们必须在这些路由中添加一些东西来检查传入的请求是否具有有效令牌。

为此,我们可以使用用于图像上传的方法。在那里,我们在路由设置中添加了额外的中间件。路由被构建为首先查看路径,然后我们使用 multer 中间件来提取传入请求中的任何文件。我们可以添加任意数量的中间件,并且想法是添加另一个额外的中间件来检查我们是否已验证。这将是我们自己创建的一个中间件,为此,我们将使用以下步骤。

1) 我们将在后端文件夹中创建一个新文件夹,并将其命名为 middleware。在此文件夹中,我们将创建一个名为 check-auth.js 的新 JavaScript 文件。

Adding Middleware to Protect Routes in MEAN Stack

2) 在此文件中,我们将导入我们的 jwt 包,导入后,我们将在此文件中导出一个东西,因为我们想在其他文件中使用此中间件,更具体地说是在我的路由文件中。我们将使用 exports 导出语法,并将其设置为一个函数,因为中间件只是一个接收我们三个熟悉的参数,即请求、响应和响应对象。这将允许我们创建一个响应和 next,如果请求应该继续,我们可以调用它。


Adding Middleware to Protect Routes in MEAN Stack

这是 Node/Express 中的典型中间件。它只是一个对传入请求执行的函数。这就是 multer 在后台所做的事情。

3) 现在,我们正在创建一个在最终函数之前运行的额外函数。在此中间件中,我们尝试从传入请求中获取令牌并将其存储在此常量中。在哪里获取令牌取决于你。我们可以将其作为查询参数从 URL 请求或解析。所以,我们可以说我们的令牌存储在我们的查询参数中,并且我们有一个 auth 字段。但是,我们希望将其作为标头接受。因此,我们将查看传入请求的标头,Express 为此提供了标头对象,并且我们期望在那里有一个 authorization 标头。

现在,我们理论上可以期望任何我们想要的标头,但 authorization 是一个通常选择的名称,用于将授权信息附加到请求。


Adding Middleware to Protect Routes in MEAN Stack

4) 现在,在那里我们期望获取我们的令牌,并且实际上我们通常使用的模式是我们将一个值赋给该标头,该值使用一个单词,即 Bearer,然后是令牌,这仅仅是一个指示。嗯,我们基本上已经将这样的令牌添加到我们的授权中,因为有身份验证替代方案,我们不使用这样的令牌。

Bearer 关键字完全取决于你,它是可选的,但经常被选中。我们在其他 API 上也看到了它,因此我们也将使用它。因为令牌,然后它是该字符串的第二部分。我们将根据它包含的空格来分割 authorization 标头。

所以,在这个 bearer 词之后,我们 then 有兴趣获取的第二个值,所以因为我们从零开始索引,所以第二个具有索引一,因为那将是空格之后的部分,所以我们的令牌。这只是一个我们可以编辑的约定。当然,我们不必期望这个 bearer 词,这样就意味着我们不能省略这个 split 逻辑。


Adding Middleware to Protect Routes in MEAN Stack

5) 现在,这给了我们令牌,我们可以检查它是否未定义,因为它不应该是未定义的,如果我们有一个令牌。现在,通常情况下,这也会失败。如果我们没有 authorization 标头,调用 split 将简单地抛出错误。所以,我们将它包装在一个 catch 块中,这意味着我们尝试进行 split,但它可能会失败,如果它失败,我们将捕获错误。如果失败,我们也知道我们没有令牌,并且我们未经验证。在这种情况下,我们将响应设置为 401 状态码(未经验证),然后根据需要发送一些 JSON 数据。


Adding Middleware to Protect Routes in MEAN Stack

6) 现在,我们将验证该令牌,为此,我们将使用 jwt verify 方法,如果验证失败,该方法也会抛出错误。所以,这也将包装在一个 try-catch 块中。在此 verify 方法中,我们将传递从传入请求中解析出的令牌。现在要使验证正常工作,我们需要传递另一个重要的信息,即 secret string,我们也用于创建令牌。


Adding Middleware to Protect Routes in MEAN Stack

7) 如果没有失败,我们想调用 next() 方法,之后,请求就可以继续了。


Adding Middleware to Protect Routes in MEAN Stack

8) 要使用该中间件,我们必须在我们的 posts 路由文件中导入它,因为我们不打算在 user.js 文件中使用该中间件。所以,我们将回到我们的 posts.js 文件,并添加一个新的 import checkAuth。


Adding Middleware to Protect Routes in MEAN Stack

9) 现在,我们通过转到我们想要保护的路由来添加该中间件,并将其作为额外的参数添加到路径之后,但在我们想要执行的所有其他逻辑之前。所以,例如,在创建帖子时,如果我们未经验证,我们甚至不想尝试提取上传的图像。所以,我们将在运行 multer 中间件之前运行它。现在,对于 put,我们在路径之后有相同的逻辑,在我们尝试获取图像之前。

注意:我们不执行此函数。我们只是将我们创建的函数的引用传递给该中间件函数,Express 将在我们收到请求时为我们执行它。


Adding Middleware to Protect Routes in MEAN Stack

Adding Middleware to Protect Routes in MEAN Stack

10) 我们提到我们想允许获取所有帖子和单个帖子,所以我们没有在那里添加中间件,但我们会为删除添加它。


Adding Middleware to Protect Routes in MEAN Stack

在下一节中,我们将把令牌附加到从前端发送的请求中,并看到我们再次使其正常工作,然后进行身份验证。