我的生产服务器上的代码有一个相当奇怪的问题。在我的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。
答案 0 :(得分:5)
我已尝试过您为另一个帖子提供地址的服务器,以解决同样的问题。 Cookie设置没有任何问题。我成功登录了。然而,有一件事引起了我的注意:到期时间。现在是格林尼治标准时间6/26/12 23:18,你的cookie到期时间设置为2012年6月27日格林威治标准时间03:18,这只是在cookie过期前4小时。
设置将在4小时后到期的Cookie是完全可以的;除非您的服务器或客户端设置了错误的日期/时间或时区。您能否确保工作/不工作的客户,当然还有您的服务器设置了正确的日期/时间和时区?我相信这可能是你遇到问题的原因。
在我开发的系统上,我给cookie一年的到期时间。我在服务器端验证会话而不依赖于cookie过期。我不使用connect进行cookie和会话管理,因为我自己总是更自在地做这些事情。但是,当您仍在使用连接时,您可以执行相同的操作。在会话设置中,您应该将cookie的maxAge设置为更高的值:
下面的代码是从连接文档中复制的。我刚刚在第三行添加了maxAge参数,将到期时间设置为一天。
connect().
.use(connect.cookieParser('keyboard cat'))
.use(connect.session({ key: 'sid', cookie: { secure: true, maxAge:86400000 }}))
我希望你的问题能够得到解决。
答案 1 :(得分:0)
以下是我要尝试的一些事情:
Ubuntu 10.04和10.10有严重错误(尤其是10.10),如果不是实例挂起,会导致速度变慢。 http://redis.io/topics/problems
您在哪里配置redis服务器连接?我认为默认情况下它会查找localhost,但在生产环境中,您通常需要指定host / port / auth(虽然我不确定您是否拥有生产环境,或者您是否正在与第三方托管,所以这可能是不适用。)
尝试将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}
还为“错误”添加事件处理程序,并查看redis是否报告任何问题:
client.on('error', function (e) {
console.log(e);
});
最后,我将生产中的环境变量转储到您的localhost dev以查看是否存在任何配置差异。有时你在开发过程中设置它们并在你开始生产时忘记它们:)
希望有所帮助!
答案 2 :(得分:0)
我发现的另一个解决方案是:当你在Debian上时,请确保你获得了不同的资质来源,以便安装最新版本的Redis。
这个问题让我忙着寻找几个小时......