NodeJS 同时使用connect.basicAuth和其他中间件

xxslljrj  于 2023-06-05  发布在  Node.js
关注(0)|答案(3)|浏览(204)

下面的代码是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();
});

我想把他们两个合并。这可能吗?

5lwkijsr

5lwkijsr1#

您可以将它们组合到您自己的中间件中,该中间件只调用两者,例如。

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两次,我已经修复了这个问题。

snvhrwxg

snvhrwxg2#

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

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.all()之前声明任何其他中间件(使用app.use())。
另一种可能性,但我对代码的结构做了一些假设,这些假设可能是错误的:

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);
  });
});
68de4m5k

68de4m5k3#

今天我无意中发现了一个片段,当我问这个问题时,它确实在做我正在看的事情。

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);
});

诀窍是在 Package 器函数中调用express.basicAuth。它是相当混乱与所有这些不同的回调虽然。

相关问题