node.js - NodeJS - 为登录或未登录的用户显示不同的内容

标签 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'
        })
    }
})

检查 session 函数:

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

最佳答案

这是一个尝试将传统的同步模型应用到Node的异步回调驱动模型中的案例。

数据库查询完成后,您将返回true,但您只是返回到数据库驱动程序。 checkSession 很久以前就返回了。由于如果存在 session.user_id,该函数将返回 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中阅读更多相关信息。 .

关于node.js - NodeJS - 为登录或未登录的用户显示不同的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11367522/

相关文章:

node.js - 认证后如何从后端重定向到前端

svn - Intellij 中的 Subversion 不断要求身份验证

javascript - NodeJS 和 Express - 分离我的 Controller 和模型

node.js - JWT 身份验证 - 防止 JWT token 被盗

node.js - Angular,未找到图像(GET 404),但运行 ng build 后显示图像

node.js - 如何使用 multer 存储具有文件扩展名的文件?

ios - 无需重定向至 facebook.com 即可从手机分享 Facebook

javascript - Expressjs : Search query api

node.js - 如何聚合 AWS SQS ApproximateNumberOfMessages

Android Titanium Appcelerator - 路径必须是字符串。收到空值