一次使用connect.basicAuth和另一个中间件

时间:2013-11-30 16:37:34

标签: node.js express connect

以下代码是2个中间件,用于为我的API执行一些最低安全性。

// API
var apiRouteV1 = '/api/v1';
app.use(apiRouteV1, express.basicAuth(function(email, token, callback){
    User.authenticateWithEmailAndToken(email, token, callback);
}));
app.use(apiRouteV1, function(req, res, next) {
    if(req.remoteUser._shop.toString() !== req.shop._id.toString())
        next(Error.http(401, 'Wrong user for this shop'));
    next();
});

我想合并他们两个。有可能吗? 谢谢!

3 个答案:

答案 0 :(得分:2)

您可以将它们组合到您自己的中间件中,这些中间件只需要同时调用它们,例如

function apiAuth(){
    var basicAuth = express.basicAuth(function(email, token, callback){
        User.authenticateWithEmailAndToken(email, token, callback);
    });
    var shopAuth = function(req, res, next) {
        if(req.remoteUser._shop.toString() !== req.shop._id.toString()){
            next(Error.http(401, 'Wrong user for this shop'));
        }
        else {
            next();
        }
    };

    return function(req, res, next){
        basicAuth(req, res, function(err){
          if (err) return next(err);

          shopAuth(req, res, next);
        });
    };
}

var apiRouteV1 = '/api/v1';
app.use(apiRouteV1, apiAuth());

另请注意,您的原始“错误用户”检查中间件会在出现错误时调用next两次,并且我已修复此问题。

答案 1 :(得分:1)

你可以像这样“组合”它们:

var apiRouteV1 = '/api/v1';

var basicAuthMiddleware = express.basicAuth(function(email, token, callback) {
  User.authenticateWithEmailAndToken(email, token, callback);
});

var myCustomMiddleware = function(req, res, next) {
  if (req.remoteUser._shop.toString() !== req.shop._id.toString())
    next(Error.http(401, 'Wrong user for this shop'));
  next();
};

app.all(apiRouteV1, basicAuthMiddleware, myCustomMiddleware);

然而,必须使用app.all()会产生微妙的副作用:Express会在您使用它时将app.router插入中间件链。因此,请确保在调用app.use()之前声明任何其他中间件(使用app.all()

另一种可能性,但我正在假设您的代码结构可能是错误的:

app.use(apiRouteV1, express.basicAuth(function(email, token, callback) {
  User.authenticateWithEmailAndToken(email, token, function(err, user) {
    if (err) return callback(err);
    if (user._shop.toString() !== req.shop._id.toString())
      return next(Error.http(401, 'Wrong user for this shop'));
    next(null, user);
  });
});

答案 2 :(得分:0)

今天,当我提出这个问题时,我偶然发现了一个正在做我正在看的内容的片段。

app.use(apiRouteV1, function(req, res, next) {
    express.basicAuth(function(email, token, callback){
        User.authenticateWithEmailAndToken(email, token, function(err, user) {
            if(err)
                return callback(err);
            if(!user)
                return callback(Error.http(401, 'Combo email:token does not match any record'));
            if(user._shop.toString() !== req.shop._id.toString())
                return callback(Error.http(401, 'Wrong user for this shop'));
            callback(null, user);
        });
    })(req, res, next);
});

诀窍是在包装函数中调用express.basicAuth。尽管如此,所有这些不同的回调都非常混乱。