下面是添加了中间件功能“checkLogin”的代码。如果用户未登录,eheckLogin中间件应该重定向到登录页面。如果用户登录,它应该呈现所请求的页面。
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.OutgoingMessage.setHeader(http.js:691:11) 在ServerResponse.res.set.res.header(/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) at 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) 在View.render(/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 200 4ms - 110b
答案 0 :(得分:2)
从您上面粘贴的代码中可以看出,您正在重定向到"登录"在等待数据库发现返回之前。尝试将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;
}
});
});
}
我已将重定向移至/ login,仅在数据库调用返回时没有匹配的用户时发生。这意味着您已搜索但未找到任何匹配项,这意味着提供的用户和密码(包含在Cookie中?)不正确。
此处的重点是仅执行res.send
或res.redirect
一次,如果我们不在中间件中执行此操作,则只需调用next()
。如果没有致电next()
,您的代码就无法点击路线代码。
但请注意,因为此代码不允许任何请求到达目的地,除非它是经过身份验证的请求。这包括favicon或资产等内容。