我有一个关于使用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'});
}
}
答案 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'));
我没有在任何地方看到你提到的回调策略。缺点是,您的代码无法读取,有许多嵌套级别,您必须将所有这些代码重复到路由器上的每个路由!