2012-06-19 36 views
2

我的生产服务器上的代码有一个相当奇怪的问题。在我的MacOS上它完美地工作,但是当我部署我的应用程序时,我无法登录。调试后,我发现我不能从req-object加载会话。这里的所有主要部件(设置,,登录页面和主页登录后)的代码NodeJS + MongoDB + Redis:注册和登录 - 会话问题

//SETTINGS 
var express = require('express'); 
var app = express.createServer(); 
var mongo = require('mongodb'), 
    Server = mongo.Server, 
    Db = mongo.Db, 
    ObjectID = require('mongodb').ObjectID; 
var BSON = require('mongodb').BSONPure; 

var RedisStore = require('connect-redis')(express); 

//connecting to mongo 
var server = new Server('localhost', 27017, { 
    auto_reconnect: true 
}); 
var db = new Db('metadocs-node_db', server); 

//setting express app 
app.set('view engine', 'ejs'); 
app.configure(function() { 
    app.use("/static", express.static(__dirname + '/static')); 
    app.use(express.bodyParser()); 
    app.use(express.cookieParser()); 
    app.use(express.session({ 
     secret: "meta-meta", 
     store: new RedisStore 
    })); 
    app.use(express.methodOverride()); 
}); 

//login page - POST for /login page 
app.post('/login', 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) { 
       req.session.user_id = doc._id; 
       res.redirect('/'); 
      } else { 
       res.render('login.ejs', { 
        success_login: 1 
       }); 
      } 
     }); 
    }); 
}); 

//GET INDEX PAGE - only after login 
app.get('/', loadUser, function (req, res) { 
    db.collection("companies", function (err, collection) { 
     collection.count(function (err, count) { 
      res.render('index.ejs', { 
       total_companies: count, 
       current_user: req.currentUser['username'] 
      }); 
     }); 
    }); 
}); 

//loadUser() is function that creates/loads user session if possible 
function loadUser(req, res, next) { 
    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; 
        next(); 
       } else { 
        res.redirect('/login'); 
       } 
      }); 
     }); 
    } else { 
     res.redirect('/login'); 
    } 
} 

这里的问题代码行:在loadUser(

if (req.session.user_id) { 

)功能。问题是req.session.user_id是空的 - 我在逐行调试每一行时发现了它。我做错了什么?它适用于我的Mac,但在Ubuntu上无效。

+0

我不知道这是否是问题或没有,但你可能要储存'req.session.user_id'为一个字符串,不是mongo.ObjectID('req.session.user_id = doc._id.toHexString()')。 –

+2

你在生产中安装了redis吗? – c0deNinja

+0

Jonathan Ong,晚上我会试试,谢谢! – f1nn

回答

5

我已经尝试了您在另一个帖子中为此相同问题提供地址的服务器。 Cookies设置没有任何问题。我登录成功。然而,有一件事引起了我的注意:到期时间。现在是格林威治标准时间6/26/12 23:18而您的Cookie到期时间设置为2012年6月27日03:18 GMT,在cookie过期前仅剩4个小时。

设置将在4小时后过期的cookie是完全可以的;除非您的服务器或客户端设置了错误的日期/时间或时区。你能否确保工作/非工作客户,当然你的服务器有正确的日期/时间和时区设置?我相信这可能是你的问题的原因。

在我开发的系统上,我给了一年的cookies过期时间。我在服务器端验证会话而不依赖于cookie过期。我不使用连接进行cookie和会话管理,因为我自己总是比较喜欢自己做这些事情。但是,当您仍在使用连接时,您可以做同样的事情。在会话设置中,您应该将maxAge设置为更高的值:

下面的代码是从connect文档复制的。我在第三行添加了maxAge参数,将过期设置为一天。

connect(). 
    .use(connect.cookieParser('keyboard cat')) 
    .use(connect.session({ key: 'sid', cookie: { secure: true, maxAge:86400000 }})) 

我希望你的问题解决了。

+0

灿烂!工作就像一个魅力!我刚刚使用:cookie:{安全:假,maxAge:86400000},并给我的会话+1天现在它适用于每个系统! :)给我的信誉+115点给你:)无法想象的问题是在会议 再次感谢! – f1nn

+0

非常感谢。你也帮了我很多。我从来没有在这里写过,因为我没有被允许发表评论,我看到的很多问题都是我想要求澄清的。你只是给了我一只手在这里开始写答案。我很高兴。 :) – hasanyasin

0

这里有一些事情我想尝试:

  1. 请确保您不使用Ubuntu 10.04或10.10:

    的Ubuntu 10.04和10.10有严重缺陷(尤其是10.10),导致慢如果不仅仅是实例挂起的话。 http://redis.io/topics/problems

  2. 你在哪里配置你的redis服务器连接?我认为默认情况下它会查看本地主机,但在生产环境中,您通常需要指定主机/端口/身份验证(尽管我不确定您是否拥有生产环境,或者您是否拥有第三方,因此可能不适用)

  3. 尝试设置no_ready_check标志,也是如此:

    client = redis.createClient(port, host, {no_ready_check: true}); 
    client.auth(password, function() { 
        console.log('Redis client connected'); 
    }); 
    //then pass client into expressjs like so: 
    ... 
    store: new RedisStore {client: client} 
    
  4. 而且添加的事件处理程序“错误”,看看是否Redis的是报告的任何问题:

    client.on('error', function (e) { 
        console.log(e); 
    }); 
    
  5. 最后,我会在生产环境和localhost dev中转储您的环境变量,以查看是否存在任何配置差异。有时你将这些设置在开发中,并在你开始制作时忘记它们:

希望对你有帮助!

0

我发现的另一个解决方案是:当您在Debian上时,确保您获得了不同的资源源,以便安装Redis的最新版本。

这个问题使我忙着寻找了几个小时......