【问题标题】:Processing all middleware in an express route处理快速路由中的所有中间件
【发布时间】:2018-01-03 03:42:38
【问题描述】:

我正在使用 express 构建 API,并且在我的路由中使用多个中间件。以下是我的端点之一

Router.route('/:id/documents')
  .get([isAuthenticated, isAdmin || isUserOwn], Users.getUserDocuments);

下面是我的中间件:

export const isAdmin = (req, res, next) => {
  if (req.decoded.role === 1) {
    next();
  } else {
    res.status(401).send({
      status: 'error',
      message: 'Only admins are authorized to access this resource',
    });
  }
};

export const isUserOwn = (req, res, next) => {
  if (req.decoded.userId === parseInt(req.params.id, 10)) {
    next();
  } else {
    res.status(401).send({
      status: 'error',
      message: 'Only the owner can access this resource',
    });
  }
};

我只希望文档的所有者和管理员能够访问该文档。我现在遇到的问题是,如果用户不是管理员,它会发送 isAdmin 响应,甚至无需访问 isUserOwn 中间件。我实际上考虑过将两者都转换为一个中间件,但我也在其他路线上单独使用它们。我如何让它同时运行?

【问题讨论】:

    标签: javascript express routing middleware


    【解决方案1】:
    function isAdminOrisUserOwn(req,res,next){
      if(req.decoded.userId === parseInt(req.params.id, 10) || req.decoded.role === 1){
       next();
      }else{
       //error
      }
    }
    

    函数通常是真实的,所以

    func1 || func2
    

    等于

    func1
    

    解决方案可能是像上面这样的额外功能,或者是一种非常复杂的方法:

    app.use(function(req,res,next){
     isAdmin(req,{ 
      status(code){
        isUserOwn(req,res,next);
        return this;
       },
       send(){}
      },next);
    

    也许最优雅的方法是一些包装函数,例如:

    function every(...funcs){
     return function(req,res,next){
       var every=false;
       funcs.reduce(function(func,middle){
         return function(){
           middle(req,res,func);
         }
       },_=>every=true);
      if(every) next() else res.error(404);
     };
    }
    
    function some(...funcs){
     return function(req,res,next){
       var some=false;
       if(funcs.some(function(middle){
              middle(req,res,_=>some=true);
              return some;
         }
       })) next() else res.error(404);
     };
    }
    

    所以你可以这样做:

    app.use(some(isAdmin,isUserOwn),...);
    

    【讨论】:

    • 谢谢乔纳斯。我很感激
    猜你喜欢
    • 2020-01-25
    • 2018-03-04
    • 2018-07-15
    • 2018-10-07
    • 2018-09-10
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 2017-05-30
    相关资源
    最近更新 更多