【问题标题】:How to find a session from MongoDB collection using Express and MongoStore如何使用 Express 和 MongoStore 从 MongoDB 集合中查找会话
【发布时间】:2014-08-18 05:48:10
【问题描述】:

我正在使用 Node/Express/Mongo 实现会话存储。我的问题是我无法从我的sessions 集合中检索任何会话,因此我无法确定用户是否已经登录。

我正在使用 MongoSkin、MongoStore 和 mongo-connect,尽管我不介意使用 Mongoose 和其他工具。

这是我的调试输出:

// Check whether the current user has a session.
// If so, adds "currentUser" to the request.
// Else, redirect to the login page.
function loadUser(req, res, next) {
    console.log("loadUser: checking loadUser...");
    var db = req.db;
    console.log("current req.session.token:");
    console.log(req.session.token);
    console.log("current req.session:");
    console.log(req.session);
    if (req.session.token) {
        // Look up the session id in the database 'sessions' collection.
        db.collection('sessions').findOne({token : req.session.token}, function(err, user) {
            console.log("found user by looking up token:");
            console.log(user);
            if (user) {
                req.currentUser = user;
                next();
            } else {
                console.log("token not in 'sessions', redirecting...");
                res.redirect('/login/webapp_login.html');
            }
        });
    } else {
        console.log("no token, redirecting...");
        res.redirect('/login/webapp_login.html');
    }
}

这是控制台输出:

loadUser: checking loadUser...
current req.session._id:
53acb8e1b7b297dc29681def
current req.session:
{ cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true },
  isLogged: 21,
  username: 'sessiontest1',
  token: '57a6dfe0bea9150bd4e2d1f76974e88b',
}
found user by looking up token:
null
token not in 'sessions', redirecting...

伴随:

        db.collection('sessions').find(req.session._id, function(user) {

我也试过了:

db.collection('sessions').findOne({session:{token:req.session.token}}, function(err, user) {

但我仍然得到null 并且函数重定向。我错过了什么吗?任何的意见都将会有帮助。我正在使用 MongoSkin,尽管我也对 Mongoose 中的解决方案持开放态度。

另外,我知道我的数据库配置正确,因为我检查了命令行:

> db.sessions.find().pretty()
{
        "_id" : "vnftBGNFVQ3S4lHiIB_omOxWDu01kFuH",
        "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":t
rue,\"path\":\"/\"},\"isLogged\":6}",
        "expires" : ISODate("2014-07-09T03:44:54.863Z")
}
{
        "_id" : "-AMKc_kIzOOAn_eQJ6RJpvTgWoargLaJ",
        "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":t
rue,\"path\":\"/\"},\"isLogged\":20,\"username\":\"sessiontest1\",\"token\":\"57a6dfe0bea
9150bd4e2d1f76974e88b\"}",
        "expires" : ISODate("2014-07-11T06:35:14.835Z")
}

出了什么问题,为什么我无法从我的 sessions 集合中检索会话?

更新 运行

db.collection('sessions').find({"session" : /./}, function(err, user) {

给了我一个输出,所以我认为问题在于将记录与会话字段字符串中的字段匹配。上面数据库输出中显示的 session 字段存在问题,因为它是一个长字符串,而不是嵌套的 JSON。

另外,我的sessions 记录在添加到我的app.js 后会自动插入:

app.use(expressSession({
    secret: 's3cretc0de',      
    store: new MongoStore({
        url: mongoUrl      
    }, function () {
        console.log("db session connection open");
    })
}));

我在路由器中添加了tokenusername 字段,如下所示:

router.get('/verify', function(req, res) {
    req.session.username = username;
    req.session.token = req.query.token;
}

我错过了什么吗?任何帮助将不胜感激。

【问题讨论】:

    标签: node.js mongodb session


    【解决方案1】:

    当您使用 MongoStore 存储会话数据时,您不需要直接查询 MongoDB。该模块为您完成所有工作。

    您可以使用req.session 来获取您的会话数据。

    因此,在您的路线中,您可以执行以下操作:

    app.get('/', function(req, res){
      // check if the username is set in the session
      if (!req.session.username) {
        // redirect it to login page
        res.redirect('/login');
      } else {
        // do something
      }
    });
    
    app.post('/login', function(req, res) {
        // you would check check the username & password here
        // if (username == '...' /&& password ...)
    
        // set the username in the session session 
        req.session.username = username; 
    });
    

    【讨论】:

    • 就是这样,谢谢。只是好奇,因为我认为 MongoSkin 是 MongoDB 的包装器:MongoSkin 也处理游标吗? MongoSkin 中对游标的适当处理是在回调之前将结果转换为数组吗?例如,如果我需要很多记录,我会使用:db.collection('myCollection').find({"key":req.session.someValue},).toArray(function(err, items) {
    • @Lucas MongoSkin 实际上包装了一些常用函数并返回承诺(以避免回调地狱)。如果您使用的是 MongoSkin,您可以使用它来处理多个项目。 toArray 示例中的方法实际上是在光标上调用的(实际上是 SkinCursor 对象)。
    • 我刚刚意识到这个答案不起作用。我的sessions 集合中有其他记录巧合地匹配{"_id": req.session._id} 谓词。我也尝试了您的原始答案{"session._id":req.session._id},但它也不起作用。当我使用谓词{"_id": /./}{"session": /./} 时,我总是得到匹配。我认为这是由于 session 字段不是嵌套的 JSON 而是文字字符串。你有什么建议吗?有没有办法选择session 字段中的字段?很抱歉造成混乱。
    • @ChristianP 如果我们需要所有会话的列表并删除/销毁特定会话。我们如何使用 MongoStore 来做到这一点
    猜你喜欢
    • 2017-04-05
    • 2018-03-30
    • 1970-01-01
    • 2019-10-21
    • 2012-08-12
    • 1970-01-01
    • 2012-03-06
    • 2014-05-03
    • 1970-01-01
    相关资源
    最近更新 更多