我试图将身份验证添加到基于Express的服务器。我注意到路由的一些奇怪的行为。在通过特定路由处理程序提供响应之后调用通用路由处理程序
我蒸的问题本明确代码:
app.get('/', function (req, res) {
console.log('this is reached first');
res.send('Hello');
});
app.get('/', function (req, res) {
console.log('this is not reached');
});
app.get('*', function (req, res) {
console.log('this is reached');
});
请求后“/”第一次处理程序被调用。它提供了一个响应,不会调用next()。因此,我很惊讶地发现第三个处理程序('*')也被称为! 另一个惊喜是传递给第三个处理程序的响应('res')与传递给第一个处理程序的响应不同。 (如果我要从第一个处理程序调用next(),那么第二个处理程序将被调用,并且具有相同的响应对象。)
现在对于我的真实场景:我想处理请求并验证全局身份验证方式。但是,有些路由应该保持可用于未经过身份验证的用户。我基于Zikes' answer的解决方案。 我首先路由了“自由”路径。然后我包含了一个全部路由处理程序('*')。如果用户通过验证,它会调用next(),否则调用next(err)。以下是所有“限制”路线。最后,我使用app.use自己的错误处理程序。它看起来像这样:
app.use(app.router);
app.use(function(err, req, res, next) {
console.log('An error occurred: ' + err);
res.send(401, 'Unauthorized');
});
app.get('/', function (req, res) {
res.send('Hello all');
});
app.all('*', function (req, res, next) {
if (req.user) {
next(); // authorized
} else {
next(new Error('401')); // unauthorized
}
});
app.get('/members', function (req, res) {
res.send('Hello member');
});
这工作得很好,阻止访问'/成员'。但是,它存在一些错误:即使在访问非限制路径('/')时也会发生身份验证检查和错误处理。发送预期响应之后,错误处理程序将尝试发送401错误响应。后者不会被发送,但代码不应该运行。
另外,此机制的副作用是未认证的用户对于不存在的页面会收到401错误。在某些情况下,我可能想要返回404。但现在我只是推...
我还挺有2个问题:
- 这种行为是错误?一般处理程序是否应该在未被调用的情况下调用?
- 什么将是一个很好的解决方案,以钩住许多但不是所有的路线,而不必单独标记它们?
你也可以使用'app.use(express.logger('dev'))'这是更好打印出来的信息 –