Node API - 在处理任何请求之前执行 GET 请求

Posted

技术标签:

【中文标题】Node API - 在处理任何请求之前执行 GET 请求【英文标题】:Node API - Do a GET Request before handling any request 【发布时间】:2019-01-15 16:46:02 【问题描述】:

我已经用一个拦截器设置了我的前端,如果存在JWT token,它总是添加一个Authorization 标头。

我有 2 个 API,一个用于检查授权,另一个用于处理任何其他数据请求(这是我正在处理的一个)。

我想在我的数据 API 中实现以下目标:

创建某种守卫(?),我可以将其放置在某些 api 路由周围,以检查是否存在 Authorization 标头。然后它需要调用不同的 API 来检查令牌是否有效。如果失败,则返回错误,否则继续执行所需的请求。

我是 node 新手,我不知道正确和最有效的方法。我没有足够的知识,所以我尝试用谷歌搜索它,但没有结果。

我并不是要你们为我写这篇文章,我只是在寻找关于如何做到这一点的想法,所以我可以更深入地研究它,因为现在我不知道该寻找什么或者如果这是可能的。

感谢您的帮助!

编辑:这是我目前处理请求的方式

路线

  /**
   * Add survey for a participant
   *
   * URL: /participant/survey
   * METHOD: POST
   */
  router.post('/participant/survey', function(req, res) 
    var bodyValidation = iValidator.json_schema(
      schema.addSurvey,
      req.body,
      'survey'
    );
    if (bodyValidation.valid == false) 
      return res.status(422).send(bodyValidation.errorMessage);
    
    participantService
      .addSurvey(req.body)
      .then(data => 
        res.status(200).send( success: true, survey: data );
      )
      .catch(err => 
        res.status(422).send(err);
      );
  );

服务

function addSurvey(survey) 
  return new Promise((resolve, reject) => 
    participantModel
      .addSurvey(survey)
      .then(data => 
        survey.id = data.insertId;
        resolve(survey);
      )
      .catch(err => 
        reject(err);
      );
  );

型号

function addSurvey(survey) 
  return new Promise((resolve, reject) => 
    db.query(
      'INSERT INTO ...',
      (error, result) => 
        if (error) 
          dbFunc.connectionRelease;
          reject(error);
         else 
          dbFunc.connectionRelease;
          resolve(result);
        
      
    );
  );

【问题讨论】:

嗨!请通读help center,尤其是How do I ask a good question? 如果您向我们展示您需要执行的请求之一的minimal reproducible example,这将使人们更容易为您提供帮助很多这个,以及授权检查代码的示例。 @T.J.Crowder 感谢您解释如何改进我的问题。我添加了一些代码以使其更清晰 授权码是什么样的? 旁注:该服务显示Promise constructor anti-pattern。你不需要,也不需要new Promise;你已经有一个来自addSurvey的承诺。只需返回链接的结果:pastebin.com/c2UmdNh5 我们不需要查看内部结构,我们需要知道您如何调用它来获得授权。但无论如何,您已有的两个答案应该足以让您弄清楚这一点。 【参考方案1】:

对于节点,您的快速 API 路由按先到先得的方式处理。因此,通常首先定义您要公开公开的所有端点,然后是受某些身份验证中间件保护的任何路由。

因此,在您的情况下,您可以做的是定义一条捕获所有路线。第一种方法将检查 Authorization 标头是否存在,如果是,则调用 next() 并且 Node JS 将继续检查下一个路由,或者如果找不到令牌,则可以在那里拒绝请求。

在您的授权功能之后,您可以检查您的 API 以了解令牌的有效性。并在这里应用相同的逻辑。您可能需要考虑根据开销/延迟缓存此响应。

app.use((req, res, next) => 
    if(<token-exists-condition>)
        if(<token-valid-condition>)
            // Pass through your middleware onto the next route
            next();
         else 
            res.status(401).send('Invalid token');
        
     else 
        res.status(401).send('No Auth Header');
    
);

有关如何使用middleware 的更多详细信息,请参阅 express 文档。

【讨论】:

【参考方案2】:

虽然这可行,但您最好使用中间件函数而不是 as Adam shows in his answer。使用这样的中间件功能更加可组合,让您专注于路由中每个路由的特定逻辑,而无需担心授权部分。只需将中间件应用到相关路由即可。


假设您的路由处理程序遵循标准模式:

router.get('/relevant/path', function (req, res) 
  res.send(/*...response...*/);
);

...然后您只需等待致电res.send,直到您对您的授权检查做出响应。你没有向我们展示那张支票,而是半伪代码:

// If it provides a promise
router.get('/relevant/path', function (req, res) 
  checkAuthorization(/*...*/)
      .then(result => 
          if (result.authorized) 
              res.send(/*...response...*/);
           else 
              res.send(/*...'not authorized' response...*/);
          
      )
      .catch(error => 
          res.send(/*...error response, auth check failed...*/);
      );
);

// If it provides a Node.js-style callback
router.get('/relevant/path', function (req, res) 
  checkAuthorization((error, result) => 
      if (error) 
          res.send(/*...error response, auth check failed...*/);
       else 
          if (result.authorized) 
              res.send(/*...response...*/);
           else 
              res.send(/*...'not authorized' response...*/);
          
      
);

【讨论】:

以上是关于Node API - 在处理任何请求之前执行 GET 请求的主要内容,如果未能解决你的问题,请参考以下文章

如何拦截 node.js 快速请求

node.js之路由,中间件,ge请求和post请求的参数

每次在 Node.js (Express.js) 中发出 API 请求之前,如何简化 Fetching Auth token?

node.js 中的 Http 请求重定向和 cookie 处理

通过 NODE JS & express & jquery 向任何 API 提交请求后,在 HTML 中打印 var 值

Node.js 之前端请求转发