2

我在生产服务器上的代码有一个相当奇怪的问题。在我的 MacOS 上它运行良好,但是当我部署我的应用程序时,我无法登录。调试后,我发现我无法从 req-object 加载会话。这是所有主要部分的代码(设置,登录页面和登录后的主页)

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

这是问题代码行:

if (req.session.user_id) {

在 loadUser() 函数中。问题是 req.session.user_id 是空的——我在逐步调试每一行时发现了它。我做错了什么?它适用于我的 Mac,但不适用于 Ubuntu。

4

3 回答 3

5

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

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

在我开发的系统上,我将 cookie 的有效期设置为一年。我在服务器端验证会话而不依赖于 cookie 过期。我不使用 connect 进行 cookie 和会话管理,因为我自己做这些事情总是更自在。但是,您仍然可以在使用 connect 时执行相同的操作。在会话设置中,您应该将 cookie 的 maxAge 设置为更高的值:

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

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

我希望你的问题可以通过这个解决。

于 2012-06-26T23:40:57.497 回答
0

以下是我会尝试的一些事情:

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

    Ubuntu 10.04 和 10.10 存在严重的错误(尤其是 10.10),如果不只是实例挂起,则会导致速度变慢。http://redis.io/topics/problems

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

  3. 尝试将 no_ready_check 标志也设置为 true:

    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. 最后,我会将您的环境变量转储到生产环境和您的本地主机开发中,以查看是否存在任何配置差异。有时您在开发中设置这些,然后在您投入生产时忘记它们:)

希望有帮助!

于 2012-06-26T18:53:28.837 回答
0

我找到的另一个解决方案是:当您使用 Debian 时,请确保您获得不同的 aptitude 源,以便您可以安装最新版本的 Redis。

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

于 2012-07-12T08:46:08.033 回答