节点API-在处理任何请求之前先执行GET请求

时间:2018-08-08 12:07:56

标签: javascript node.js api express jwt

我为前端设置了一个拦截器,如果存在Authorization,则总是添加一个JWT token头。

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

我要在数据API中实现的目标如下:

创建某种类型的guard(?),可以将其放置在某些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);
        }
      }
    );
  });
}

2 个答案:

答案 0 :(得分:2)

对于节点,您的Express 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的更多详细信息,请参考快速文档。

答案 1 :(得分:1)

虽然这可行,但最好使用中间件功能代替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...*/);
          }
      }
});