node.js和express - 使用多个中间件与回调 - 什么是最佳实践?

时间:2015-09-27 16:18:57

标签: javascript node.js express

我有一个关于使用express构建HTTP服务的问题,需要在运行实际函数之前运行一些预检查(如果其中一个预检查失败,则不运行该函数)。

例如,首先检查请求是否已获得授权,然后检查权限,并且仅当两个传递都运行实际功能时才检查。 通过将授权和权限都写为中间件或使用回调,我可以想到使用express的两种方法。

哪种方法是快递的最佳做法?使用中间件看起来更优雅,但它更好吗?两种解决方案的优缺点是什么?

使用回调功能如下所示:

router.get( '/myResource',, function(req, res){ 
  autorizationCB(function(err, data){
    if (err) {
      return res.status(401).json({message: err.message});
    } 
    permissionsCB(function (err, data) {
      if (err) {
        return res.status(403).json({message: err.message});
      }
      // actual resource code...
    });
  });
});

function authorizationCB(callback) {
  // check authorization
  ...
  ...
  if (authorized) {
    return callback(null, data);
  } else { 
    return callback({message: 'some authorization error msg'});
  }
}
function permissionsCB(callback) {
  // check permissions
  ...
  ...
  if (permitted) {
    return callback(null, data);
  } else { 
    return callback({message: 'some permissions error msg'});
  }
}

中间件看起来像这样:

router.get('/myResource', 
   authurizationMW, 
   permissionsMw, 
   function(req, res){ 
      // actual resource code...
   });

function authorizationMW(req, res, next) {
  //check if authorized
  ...
  ...
  if (authorized) {
    next();
  } else {
    res.status(401).json({message: 'not authorized'});
  }
}
function permissionsMW(req, res, next) {
  //check if permitted
  ...
  ...
  if (permitted) {
    next();
  } else {
    res.status(403).json({message: 'no permissions'});
  }
}

2 个答案:

答案 0 :(得分:2)

中间件更可重复使用。 我实际上会做这样的事情,例如关于如何更好地重用:

var secureRouter = ...
secureRouter.use(authorizationMW);
secureRouter.use(permissionsMW);

var appRouter = ....
secureRouter.use(appRouter);

//all routes are protected....
appRouter.get('/myResource', 
   function(req, res){ 
      // actual resource code...
   });
);
appRouter.get('/myResource2', 
   function(req, res){ 
      // actual resource code...
   });
);
//.. so on....

答案 1 :(得分:2)

实际上,中间件正是出于这些目的,并且使用它们不需要为每条路由添加所需的中间件,您可以将它们添加到路由器中,它们只会被路由器下的路由调用:

app.use('/user', authorizationMW, permissionsMW, require('./routes/user'));

我没有在任何地方看到你提到的回调策略。缺点是,您的代码无法读取,有许多嵌套级别,您必须将所有这些代码重复到路由器上的每个路由!