0
我寫了一個快速應用程序來創建一個REST API。Express.js:錯誤處理程序後,執行不會停止。爲什麼?
據我瞭解這一點,如果我發送一個報頭具有無效令牌,jwt.verify套犯錯(JsonWebTokenError),這是傳遞給我的錯誤處理程序,並把它發送401:
res.status(401).send({
success: false,
message: err.name
});
和執行應該結束。但相反,我得到這個:
Start token verification
Error before: JsonWebTokenError
JsonWebTokenError: invalid signature
at Object.module.exports.verify (/srv/lonja/node_modules/jsonwebtoken/index.js:129:17)
at /srv/lonja/app/routes/api.js:76:17
at Layer.handle [as handle_request] (/srv/lonja/node_modules/express/lib/router/layer.js:82:5)
at trim_prefix (/srv/lonja/node_modules/express/lib/router/index.js:302:13)
at /srv/lonja/node_modules/express/lib/router/index.js:270:7
at Function.proto.process_params (/srv/lonja/node_modules/express/lib/router/index.js:321:12)
at next (/srv/lonja/node_modules/express/lib/router/index.js:261:10)
at Function.proto.handle (/srv/lonja/node_modules/express/lib/router/index.js:166:3)
at router (/srv/lonja/node_modules/express/lib/router/index.js:35:12)
at Layer.handle [as handle_request] (/srv/lonja/node_modules/express/lib/router/layer.js:82:5)
This is the last message related to[object Object]
GET /api/home_gallery/ 401 20.834 ms - 47
_http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (/srv/lonja/node_modules/express/lib/response.js:700:10)
at ServerResponse.send (/srv/lonja/node_modules/express/lib/response.js:154:12)
at ServerResponse.json (/srv/lonja/node_modules/express/lib/response.js:240:15)
at /srv/lonja/app/routes/api.js:214:17
at /srv/lonja/node_modules/mongoose/node_modules/kareem/index.js:103:16
at process._tickCallback (node.js:355:11)
所以,在錯誤處理後,執行路由處理程序,我不明白爲什麼。
我的代碼(只是相關位):
var User = require('../models/user');
var myImage = require('../models/image');
var jwt = require('jsonwebtoken');
var config = require('../../config');
// super secret for creating tokens
var superSecret = config.secret;
module.exports = function(app, express) {
var apiRouter = express.Router();
我用這個中間件來驗證jsonwebtoken:
// route middleware to verify a token
apiRouter.use(function(req, res, next) {
// do logging
console.log('Start token verification');
// check header or url parameters or post parameters for token
var token = req.body.token || req.params.token || req.headers['x-access-token'];
// decode token
// verifies secret and checks exp
if (token) {
jwt.verify(token, superSecret, function(err, decoded) {
if (err) {
return next(err);
}
// if everything is good, save to request for use in other routes
else req.decoded = decoded;
});
}
// if there is no token
// return an HTTP response of 401 (access unauthorized) and an error message
else {
var noToken = new Error('Error_NoTokenProvided');
return next(noToken);
}
next(); // make sure we go to the next routes and don't stop here
});
稍後在代碼中,我有這個路由處理:
apiRouter.route('/home_gallery')
// get all the images
.get(function(req, res) {
myImage.find(function(err, images) {
if (err) res.send(err);
// return the users
res.json(images);
});
});
最後,這最後一塊中間件做錯誤處理:
apiRouter.use(function(err, req, res, next) {
console.log('Error before: ' + err.name);
if (err.name == 'Error_NoTokenProvided' ||
err.name == 'JsonWebTokenError') {
res.status(401).send({
success: false,
message: err.name
});
} else if (err.name == 'TokenExpiredError') {
res.redirect('/login');
} else {
res.status(500).send({
success: false,
message: err.name
});
}
console.log(err.stack);
console.log('This is the last message related to' + req);
});
我一直在想這件事,我有一個疑問,是不是轉換代碼同步執行所有這些「if else」語句。執行必須等待_asyncronous_調用才能繼續執行,否則我錯過了一些東西? – mvillar
@mvillar這裏的異步函數是'jwt.verify()',我們等待在調用next()之前完成它(在完成回調函數中調用'jwt.verify()') 。 'if/else'只是爲了區分哪個調用要'next()'。 – robertklep