[英]NodeJS + MongoDB + Redis: Register and login - sessions issue
我在生產服務器上的代碼遇到了一個非常奇怪的問題。 在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上運行。
我已經嘗試過在服務器上為同一問題在另一個帖子中提供地址的服務器。 Cookie設置沒有任何問題。 我已成功登錄。 但是,有一件事引起了我的注意:到期時間。 現在是格林尼治標准時間6/26/12 23:18,您的Cookie過期設置為2012年6月27日格林尼治標准時間,即Cookie過期僅剩下4個小時。
設置可以在4小時后過期的cookie完全可以; 除非您的服務器或客戶端的日期/時間或時區設置錯誤。 您能否確定工作/不工作的客戶端以及您的服務器是否設置了正確的日期/時間和時區? 我相信這可能是您遇到問題的原因。
在我開發的系統上,我給出cookie的有效期為一年。 我在不依賴Cookie過期的情況下在服務器端驗證會話。 我不使用connect來進行cookie和會話管理,因為我總是更願意自己做這些事情。 但是,當您仍在使用connect時,您可以做同樣的事情。 在會話設置中,您應該將cookie的maxAge設置為更高的值:
下面的代碼是從connect文檔中復制的。 我剛剛在第三行添加了maxAge參數,將過期設置為一天。
connect().
.use(connect.cookieParser('keyboard cat'))
.use(connect.session({ key: 'sid', cookie: { secure: true, maxAge:86400000 }}))
希望您的問題能解決。
這是我嘗試的一些方法:
Ubuntu 10.04和10.10有嚴重的錯誤(尤其是10.10),即使不僅僅是實例掛起,它們也會導致速度降低。 http://redis.io/topics/problems
您在哪里配置Redis服務器連接? 我認為默認情況下它將查找localhost,但在生產環境中,通常需要指定主機/端口/身份驗證(盡管我不確定您是生產環境的所有者還是第三方托管,因此這可能不適用。)
嘗試將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); });
最后,我將在生產環境和本地開發環境中轉儲您的環境變量,以查看是否存在任何配置差異。 有時,您在開發中設置了這些功能,而在生產時就忘記了它們:)
希望有幫助!
我發現的另一個解決方案是:在使用Debian時,請確保獲得不同的智能源,以便可以安裝最新版本的Redis。
這個問題使我忙於搜索幾個小時...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.