Node.js NodeJS-为登录或未登录的用户显示不同的内容
我试图在一个页面上为登录用户而不是用户显示不同的内容 以下是我用于生成/页面的代码:Node.js NodeJS-为登录或未登录的用户显示不同的内容,node.js,authentication,express,Node.js,Authentication,Express,我试图在一个页面上为登录用户而不是用户显示不同的内容 以下是我用于生成/页面的代码: app.get('/',function(req, res){ if (!checkSession(req, res)) { res.render('index.ejs', { title: 'FrontSpeak - blog-based social network' }) } else { res.render('ind
app.get('/',function(req, res){
if (!checkSession(req, res)) {
res.render('index.ejs', {
title: 'FrontSpeak - blog-based social network'
})
} else {
res.render('index.ejs', {
title: 'autrhorized'
})
}
})
检查会话功能:
function checkSession(req, res) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
return true;
} else {
return false;
}
});
});
} else {
return false;
}
}
app.post('/', function(req, res){
db.collection("users", function (err, collection) {
collection.findOne({ username: req.body.username }, function (err, doc) {
if (doc && doc.password == req.body.password) {
console.log("user found");
req.session.user_id = doc._id;
}
}
});
});
});
app.post('/', function(req, res){
db.collection("users", function (err, collection) {
collection.findOne({ username: req.body.username }, function (err, doc) {
console.log('found user');
if (doc && doc.password == req.body.password) {
req.session.user_id = doc._id;
res.redirect('/');
};
res.redirect('/');
});
res.redirect('/');
});
});
function checkLogin(req, res, next) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
if (err) return next(err); // handle errors!
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
} else {
req.currentUser = null;
}
next();
});
});
} else {
req.currentUser = null;
next();
}
}
登录功能:
function checkSession(req, res) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
return true;
} else {
return false;
}
});
});
} else {
return false;
}
}
app.post('/', function(req, res){
db.collection("users", function (err, collection) {
collection.findOne({ username: req.body.username }, function (err, doc) {
if (doc && doc.password == req.body.password) {
console.log("user found");
req.session.user_id = doc._id;
}
}
});
});
});
app.post('/', function(req, res){
db.collection("users", function (err, collection) {
collection.findOne({ username: req.body.username }, function (err, doc) {
console.log('found user');
if (doc && doc.password == req.body.password) {
req.session.user_id = doc._id;
res.redirect('/');
};
res.redirect('/');
});
res.redirect('/');
});
});
function checkLogin(req, res, next) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
if (err) return next(err); // handle errors!
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
} else {
req.currentUser = null;
}
next();
});
});
} else {
req.currentUser = null;
next();
}
}
所以,它似乎不起作用。但是,我认为这不是显示不同内容的最佳方式。也许有更优雅的方法可以做到这一点?谢谢大家!
更新:新登录功能:
function checkSession(req, res) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
return true;
} else {
return false;
}
});
});
} else {
return false;
}
}
app.post('/', function(req, res){
db.collection("users", function (err, collection) {
collection.findOne({ username: req.body.username }, function (err, doc) {
if (doc && doc.password == req.body.password) {
console.log("user found");
req.session.user_id = doc._id;
}
}
});
});
});
app.post('/', function(req, res){
db.collection("users", function (err, collection) {
collection.findOne({ username: req.body.username }, function (err, doc) {
console.log('found user');
if (doc && doc.password == req.body.password) {
req.session.user_id = doc._id;
res.redirect('/');
};
res.redirect('/');
});
res.redirect('/');
});
});
function checkLogin(req, res, next) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
if (err) return next(err); // handle errors!
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
} else {
req.currentUser = null;
}
next();
});
});
} else {
req.currentUser = null;
next();
}
}
看起来您正试图通过检查其返回值将
checkSession
用作同步函数,但是checkSession
不能同步,因为它依赖于异步功能,即此处的回调:db.collection('users',function(err,collection)…
。您需要将检查会话
修改为异步:
function checkSession(req, res, callback) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
callback(true);
} else {
callback(false);
}
});
});
} else {
callback(false);
}
}
然后在请求处理程序中异步使用它:
app.get('/',function(req, res){
checkSession(req, res, function(isUser) {
if (!isUser) {
res.render('index.ejs', {
title: 'FrontSpeak - blog-based social network'
})
} else {
res.render('index.ejs', {
title: 'autrhorized'
})
}
});
})
这是一个尝试将传统的同步模型应用于节点的异步回调驱动模型的案例 数据库查询完成后,返回
true
,但您只是返回数据库驱动程序。checkSession
很久以前就返回了。由于如果存在会话,该函数将返回未定义的值。用户id
(如果没有,则返回false
),因此登录检查将始终计算为false
相反,您可以使用Brandon的建议使checkSession
异步,或者我建议实现一个中间件功能:
function checkSession(req, res) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
return true;
} else {
return false;
}
});
});
} else {
return false;
}
}
app.post('/', function(req, res){
db.collection("users", function (err, collection) {
collection.findOne({ username: req.body.username }, function (err, doc) {
if (doc && doc.password == req.body.password) {
console.log("user found");
req.session.user_id = doc._id;
}
}
});
});
});
app.post('/', function(req, res){
db.collection("users", function (err, collection) {
collection.findOne({ username: req.body.username }, function (err, doc) {
console.log('found user');
if (doc && doc.password == req.body.password) {
req.session.user_id = doc._id;
res.redirect('/');
};
res.redirect('/');
});
res.redirect('/');
});
});
function checkLogin(req, res, next) {
if (req.session.user_id) {
db.collection('users', function (err, collection) {
if (err) return next(err); // handle errors!
collection.findOne({
_id: new ObjectID(req.session.user_id)
}, function (err, user) {
if (user) {
req.currentUser = user;
} else {
req.currentUser = null;
}
next();
});
});
} else {
req.currentUser = null;
next();
}
}
现在您有两种使用中间件功能的方法。如果您想在每个请求中检查用户,只需将其添加到应用程序中:
app.use(checkLogin);
现在,每个请求都会有一个req.currentUser
,但是您会遇到从数据库中获取每个请求的登录状态的性能问题。或者,如果您只需要某些请求的用户信息,请将该函数粘贴在路由中:
app.get('/', checkLogin, function(req, res) {
if (req.currentUser) {
// logged in
} else {
// not
}
});
您可以在中阅读更多信息。谢谢,我了解中间件,这是一个完美的解决方案。但有一个问题:如果checkLogin返回null,那么get()就可以了不会执行。我需要向已登录和未登录的用户显示内容。
checkLogin
返回什么并不重要。请这样想:当GET
请求/
时,checkLogin
首先运行(因为它是回调列表中的第一个)。它触发一个DB查询,然后函数什么也不返回。当DB调用完成时,回调会触发,分配给req
,然后调用next
next
是神奇的调味品:这是Express调用下一个路由处理程序的方式,在这种情况下是app.get(…)中的匿名函数
line。现在在匿名路由处理程序函数中,您只需检查req.currentUser==null
并呈现相应的视图。节点无法找到req的会话属性是否重要?移动的app.use(checkLogin);离开app.configure(函数(){}它成功了!谢谢!是的,你必须确保你的中间件函数在会话中间件之后运行。中间件函数按照它们添加的顺序运行,因此如果你的函数是在会话函数之前添加的,那么当你的函数被调用时,req.Session
显然还不存在。