我正在尝试添加可能阻止访问网站部分的身份验证中间件:
app = express()
.get('/api/test', function (req, res) { ... })
.use('/api', function (req, res, next) {
if (req.param('key')) {
next();
} else {
res.json(401, {
message : 'Authentication failed'
});
res.end();
}
})
.get('/api/data', function (req, res) { ... });
我期望调用/ api / data将首先由密钥检查器处理,然后(如果成功)由/ api / data处理程序处理。但是首先由'/ api / data'处理请求。
检查器似乎适用于/ api / something_that_does_not_exist,但不适用于/ api / something_that_exist。
也许我错过了express / connect文档中的内容?
更新我已经跟踪了这一事实,即第一个get / post调用初始化路由器中间件,因此首先执行它。
答案 0 :(得分:6)
一旦声明了路由,Express就会在设置应用时将router
中间件插入中间件堆栈。
在您的情况下,因为在插入密钥检查中间件之前插入.get('/api/test', ...)
,路由器中间件会被插入并优先使用(也适用于您稍后声明的/api/data
路由)和密钥检查程序永远不会被称为。
以下是两种解决方案:
// separate middleware, used for all routes that need checking
var keyChecker = function(req, res, next) {
...
};
app.get('/api/test', function(req, res) { ... });
app.get('/api/data', keyChecker, function(req, res) { ... });
// or, as an alternative, create a 'catch-all' route between the routes that don't
// need to be checked, and the ones that should; this will also match non-existing
// routes (like '/api/foobar'), which might or might not be an issue;
app.get('/api/test', function(req, res) { ... });
app.all('/api/*', function(req, res, next) { // 'all' means 'all methods'
// keychecker code
});
app.get('/api/data', function(req, res) { ... });
第三种解决方案可能是在密钥检查中间件本身(/api/test
)中明确检查req.path === '/api/test'
,如果匹配则只调用next()
。