Как найти сеанс из коллекции MongoDB с помощью Express и MongoStore

#node.js #mongodb #session

#node.js #mongodb #сеанс

Вопрос:

Я реализую хранилище сеансов с использованием 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» : /./}, функция (ошибка, пользователь) {

выдает мне вывод, поэтому я считаю, что проблема заключается в сопоставлении записи с полем в строке поля сеанса. session Поле, показанное в выводе базы данных выше, проблематично, потому что это одна длинная строка, а не вложенный JSON.

Кроме того, мои sessions записи вставляются автоматически после добавления этого в мой app.js :

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

И я добавил поля token и username в свой маршрутизатор, как показано ниже:

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

Я что-то упустил? Любая помощь будет принята с благодарностью.

Ответ №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 amp; password here
    // if (username == '...' /amp;amp; password ...)

    // set the username in the session session 
    req.session.username = username; 
});
 

Комментарии:

1. Это было все, спасибо. Просто любопытно, поскольку я думал, что MongoSkin — это оболочка для MongoDB: MongoSkin также обрабатывает курсоры? Будет ли подходящей обработка курсора в MongoSkin для преобразования результата в массив перед обратным вызовом? Например, если бы мне нужно было много записей, я бы использовал: db.collection('myCollection').find({"key":req.session.someValue},).toArray(function(err, items) { ?

2. @Lucas MongoSkin фактически оборачивает некоторые общие функции и возвращает обещания (чтобы избежать ада обратного вызова). Если вы используете MongoSkin, вы можете использовать его таким образом для обработки нескольких элементов. toArray метод в вашем примере фактически вызывается для курсора (фактически, объекта SkinCursor).

3. Я только что понял, что этот ответ не работает. В моей коллекции были другие записи sessions , которые по совпадению соответствовали {"_id": req.session._id} предикату. Я также попробовал ваш оригинальный ответ, {"session._id":req.session._id} но он тоже не работает. Когда я использую предикаты {"_id": /./} или {"session": /./} , я всегда получаю совпадение. Я думаю, это связано с session тем, что поле не является вложенным JSON, а является буквальной строкой. У вас есть какие-либо предложения? Есть ли способ выбрать для полей внутри session поля? Извините за путаницу.

4. @ChristianP если нам нужен список всех сеансов и удалить / уничтожить конкретный. Как мы можем это сделать с помощью MongoStore