nodejs passport - 在 api 中使用相同的路由,但 return 基于权限的不同数据集

nodejs passport - use same routes in api but return different sets of data based on permissions

不确定如何处理他的问题。假设我有这个端点:

GET /api/Books/

对于网络服务上的用户,这将return 用户的资源。它可能看起来有点像这样:

exports.getBooks = function(req, res) {
  // find all books for user
  BookModel.find({ userId: req.user._id }, function(err, books) {
    if (err)
      res.send(err);

    res.json(books);
  });
};

使用api的网络服务需要用户先登录。我可以使用基本的护照策略来确保身份验证来实现这一点。但是假设我有一个管理员帐户需要查看所有记录过的书籍。更重要的是,管理员帐户和用户帐户具有完全不同的属性,因此分配 Boolean 权限是不够的。使用相同的端点:

GET /api/Books

我认为没有理由编写另一个端点来实现此目的。然而,差异看起来像这样:

exports.getBooks = function(req, res) {
   // find all books in the database
   BookModel.find({}, function(err, books) {
     if (err)
       res.send(err);

     res.json(books);
   });
 };

但是我无法想出一个干净的方法来实现这一点,同时还按预期使用护照中间件:

router.route('/books')
  .post(authController.isAuthenticated, bookController.postBooks)
  .get(authController.isAuthenticated, bookController.getBooks);

函数isAuthenticated只会验证请求资源的用户是否有权限,不会改变控制器的行为方式。我乐于接受想法。

回答

用户@ZeroCho 建议检查 req.user 对象中的用户属性以确定应发回的内容。这比我预想的要简单。在 passport.BasicAuth 策略的实施中,我检查了哪个 table 有匹配的文档。一旦在普通用户或管理员用户 table 中找到用户,您所做的就是在 isMatch return 对象中添加一个 属性。

   // Basic strategy for users
   passport.use('basic', new BasicStrategy(
      function(email, password, done) {
       verifyUserPassword(email, password,
    function(err, isMatch) {
      if(err) { return done(err); }

      // Password did not match
      if(!isMatch) { return done(null, false); }

      // Success
      var userInfo = {
        email: email,
        isAdmin: isMatch.isAdmin || false,
        businessID: isMatch.businessID || false
      };

      return done(null, userInfo);
    });
  })
    );

然后您可以检查 .isAdmin.businessID 在您的请求中是否有效。

只需通过 if 语句分隔您的控制器

exports.getBooks = function(req, res) {
  if (req.user.isAdmin) { // or some other code to check user is admin
    // find all books in the database
    BookModel.find({}, function(err, books) {
      if (err)
        res.send(err);
      res.json(books);
    });
  } else {
    BookModel.find({ userId: req.user._id }, function(err, books) {
      if (err)
        res.send(err);
      res.json(books);
    });
  }
};