NodeJS - 显示登录或不登录用户的不同内容

时间:2012-07-06 18:10:16

标签: 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('index.ejs', {
            title: 'autrhorized'
        })
    }
})

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('/');  
    });
});

2 个答案:

答案 0 :(得分:2)

这是尝试将传统同步模型应用于Node的异步回调驱动模型的情况。

数据库查询完成后,返回true,但您只是返回数据库驱动程序。 checkSession很久以前就回来了。如果有session.user_id(如果没有false,则该函数返回 undefined ,登录检查将始终评估为false。

相反,您可以使用Brandon的建议使checkSession异步,或者我建议实现中间件功能:

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
    }
});

您可以在the Express docs中了解详情。

答案 1 :(得分:0)

看起来您正在尝试通过检查其返回值来使用checkSession作为同步函数,但checkSession不能同步,因为它依赖于异步功能,即此处的回调:{{ 1}}。您需要将db.collection('users', function (err, collection) ...修改为异步:

checkSession

然后在请求处理程序中异步使用它:

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);
}
}