我試圖將身份驗證添加到基於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'))'這是更好打印出來的信息 –