#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