在express4中停止中间件链

下面是添加了中间件function“checkLogin”的代码。 如果用户没有login,eheckLogin中间件应该redirect到login页面。如果用户login,它应该呈现请求的页面。

var express = require('express'); var router = express.Router(); var mongoUri = 'mongodb://localhost/mydb'; var MongoClient = require('mongodb').MongoClient; function mongoDBConnect(req, res, next) { MongoClient.connect('mongodb://localhost/gadda_db', function(err, db) { if(!err) { req.db = db; next(); } else { res.send('unable to connect to mongodb: err = ' + err); } }); }; function checkLogin(req, res, next) { if (req.loggedin) { next(); return; } if (req.loggedin && req.url === '/login') { res.redirect('http://' + 'localhost:3000' + '/game/my_game'); return; } if (!req.loggedin && req.url === '/login') { next(); return; } req.db.collection('game_users', function (err, collection) { if (err) { res.send("error while reading game_users: err " + err); } collection.findOne({user: req.cookies.user, password: req.cookies.password}, function (err, user) { if (err) { res.send("error here"); return; } req.loggedin = true; next(); return; }); }); res.redirect('login'); return; }; router.use(mongoDBConnect); router.use(checkLogin); router.get('/', function(req, res) { res.redirect('http://' + 'localhost:3000' + '/game/my_game'); }); router.get('/login', function(req, res) { res.render('gadda_login', {title: 'gadda', error: ''}); }); 

当发送到localhost:3000 / gadda的请求时,服务器上将打印以下错误消息

GET / gadda / 302 34ms – 66b错误:发送后无法设置标题。 ServerResponse.res.set.res.header处的ServerResponse.OutgoingMessage.setHeader(http.js:691:11)(/home/hhk/src/nodejs_projects/gadda_v2/node_modules/express/lib/response.js:551:10 )在ServerResponse.res.send(/home/hhk/src/nodejs_projects/gadda_v2/node_modules/express/lib/response.js:132:12)在fn(/ home / hhk / src / nodejs_projects / gadda_v2 / node_modules / express /lib/response.js:778:10)在View.exports.renderFile [作为引擎](/home/hhk/src/nodejs_projects/gadda_v2/node_modules/ejs/lib/ejs.js:318:3)。渲染(/home/hhk/src/nodejs_projects/gadda_v2/node_modules/express/lib/view.js:76:8)在Function.app.render(/ home / hhk / src / nodejs_projects / gadda_v2 / node_modules / express / lib /application.js:519:10)在ServerResponse.res.render(/home/hhk/src/nodejs_projects/gadda_v2/node_modules/express/lib/response.js:782:7)在Layer.module.exports [作为句柄(/home/hhk/src/nodejs_projects/gadda_v2/app.js:54:9)在trim_prefix(/ home / hhk / src / nodejs_projects / gadda_v2 / node_modules / express / lib / router / index。 js:252:17)router.get / login GET / gadda / login 200 11ms – 546b GET /stylesheets/style.css 200ms – 110b

从上面粘贴的代码看来,在等待数据库查找返回之前,您正在redirect到“login”。 尝试重构您的checkLogin函数到以下内容:

 function checkLogin(req, res, next) { if (req.loggedin) { if (req.url === '/login') { res.redirect('http://' + 'localhost:3000' + '/game/my_game'); return; } next(); return; } if (!req.loggedin && req.url === '/login') { next(); return; } req.db.collection('game_users', function(err, collection) { if (err) { res.send("error while reading game_users: err " + err); return; } collection.findOne({ user: req.cookies.user, password: req.cookies.password }, function(err, user) { if (err) { res.send("error here"); return; } if (user) { req.loggedin = true; next(); return; } else { res.redirect('/login'); return; } }); }); } 

我已经将redirect移动到/login只发生在数据库调用没有匹配的用户时返回。 这意味着你已经search,但没有find任何匹配,这意味着提供的用户和密码(包含在cookie中?)是不正确的。

这里的要点是只执行res.sendres.redirect一次,如果不在中间件中执行,只需调用next() 。 通过不调用next()你的代码将不会命中路由代码。

这里要小心,因为这个代码不会允许任何请求到达目的地,除非它是一个authentication请求。 这包括像图标或资产的东西。