2012-10-03 79 views
5

我以前做過這個......我不明白我在做什麼錯的這個時候,但我一直在掙扎了幾個小時,現在考慮自己精神上受阻。對應的代碼:的NodeJS:快遞+ RedisStore,req.session未定義

app.use(express.bodyParser()); 
app.use(i18next.handle); 
app.use(express.methodOverride()); 
app.use(express.static(__dirname + '/public')); 
app.set('views', __dirname + '/views'); 
app.set('view engine', 'swig'); 
app.set('view cache', false); 
var session_store = new RedisStore({ client : redis_client}); 
app.use(express.errorHandler({ dumpExceptions : true, showStack : true})); 
app.use(express.cookieParser()); 
app.use(express.session({ store : session_store, secret : SESSION_SECRET, key : "sid" })); 
app.use(app.router); 

然後處理請求的時候,這裏只是一個例子:

app.get('/session_test', function (req, res, next) { 
    console.log(req.session); //undefined 
}); 

連接到Redis的工作就好了。沒有顯示錯誤。然後,當試圖從請求訪問它時,req.session是未定義的。瀏覽器正在發送正確的sid。

我在該請求期間發生的確切流量不是專家,但調試完畢後,它好像路由器在會話中間件之前被調用。

預先感謝任何及所有可能的幫助。我會提供任何我可以的代碼,我不確定可能有什麼幫助。

這裏有更多的代碼。 server.js

//Dependency modules 
var express = require('express'), 
    app = express.createServer(), 
    //Application dependency modules 
    settings = require('./settings'), //app settings 
    routes = require('./routes'), //http routes 
    rtroutes = require('./rtroutes'); //real time communication routes (io) 

var io = require('socket.io').listen(app); 
var appWithSettings = settings.setup(io, app); 

routes.settings.setup(appWithSettings); 
rtroutes.settings.setup(io, appWithSettings); 

沒有路由添加到routes.settings.setup被調用。設置(這是全局設置)是一個非常大的文件。這就是所有配置完成的地方。除非調用settings.setup方法,否則不會添加設置。下面是該文件的一個切口:

//Dependency modules 
var express = require('express'), 
    redis = require('redis'), 
//Important configuration values 
var SESSION_SECRET = 'some secret thing which doesnt belong to stackoverflow!', 
    insert_other_variables_here = "lalala"; 

//Computed general objects 

var RedisStore = require('connect-redis')(express), 
    redis_client = redis.createClient(REDIS_PORT, REDIS_HOST); 

exports.setup = function (io, app) { 
    app.configure(function() { 
    app.use(express.bodyParser()); 
    app.use(i18next.handle); 
    app.use(express.methodOverride()); 
    app.use(express.static(__dirname + '/public')); 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'swig'); 
    app.set('view cache', false); 
    var session_store = new RedisStore({ client : redis_client}); 
    app.use(express.errorHandler({ dumpExceptions : true, showStack : true})); 
    app.use(express.cookieParser()); 
    console.log("ABOUT TO ADD SESSION STORE MIDDLEWARE"); 
    app.use(express.session({ store : session_store, secret : SESSION_SECRET, key : "sid" })); 
    console.log("AND NOW ADDED THE SESSION STORE MIDDLEWARE"); 
    app.use(app.router); 
    }); 

    app.configure('development', function() { 
    //some things in here, but nothing that affects app. I have commented this 
    //for debugging and it changed nothing 
    }); 

    app.configure('production', function() { 
    //mostly configuration for io and some caching layers, as well as servers info 
    app.use(express.errorHandler()); 
    app.use(express.logger({ stream : logFile })); 
    }); 
    app.listen(WEB_PORT); 
    return { 
    app : app, 
    //some other stuff that isn't relevant 
    } 
} 

我已經25條路線一分爲4頁不同的文件(不知何故,我沒有必要爲會議到現在爲止,因爲我將推遲一些地方和所需的一切都與貓鼬做)。下面是它是如何正在做一個例子(用假名字):

路線/ index.js

export.settings = require("./settings"); 

路線/ settings.js

exports.setup = function (app_settings) { 
    require("./route1")(app_settings); 
    require("./route2")(app_settings); 
    require("./route3")(app_settings); 
}; 

這裏有一個剝離出來 「路徑1」文件(「路線/ route1.js」):

module.exports = function (app_settings) { 
    var app = app_settings.app; 
    console.log("ABOUT TO ADD ROUTES") 
    app.get("/signin", function (req, res, next) { 
    console.log(req.session); //this will be undefined 
    }); 
    app.get("/register", function (req, res, next) { 
    }); 
    app.get('/language', function (req, res, next) { 
    }); 
    app.post('/settings', function (req, res, next) { 
    }); 
    console.log("ADDED ROUTES NOW!") 
} 
+0

你有這一行有兩次:app.use(express.session({店:session_store,祕密:SESSION_SECRET,鍵: 「SID」})); – chovy

+0

我的不好,我粘貼了兩次代碼(所有行都在那裏兩次) – Mamsaac

+0

是否解決了這個問題?我沒有看到你使用req的地方。session – chovy

回答

9

無論何時定義的路由,路由器就會自動插入任何中間ware堆棧在那個時候(後來有意插入它的嘗試將被忽略)。在設置會話處理程序之前,您確定沒有定義任何路線嗎?

+0

是的。這是一個讓我想起來的想法......所以我在添加會話中間件之前和之後添加console.log,並且在添加路由之前和之後,輸出會首先出現在會話中(但在添加之前和之後),然後是路由。中間件訂單是否可能通過我的某些操作重置? – Mamsaac

+0

你可以嘗試在調用'router'之後調用'static'的調用。我不熟悉'i18next',所以我不知道這是否會導致問題。您也可以嘗試將'errorhandler'移動到堆棧的末尾;它可能在現在的位置,它缺少源於'session'的錯誤。 – ebohlman

+0

我注意到i18next和errorhandler沒有修復。我將靜態移動到app.router下面(注意我禁用靜態生產,因爲我使用nginx)並且仍然沒有幫助。我仍然認爲你在正確的軌道上,但我不知道我搞砸了什麼:( – Mamsaac

3

忘了更新的:Ebohlman設置我在正確的軌道上。

這是i18next。當調用其中一個init方法時,它會設置路由,並迫使app.router更早地被強制進入句柄堆棧。我的壞,我沒有意識到代碼的一部分是與應用程序對象交互,它確實。 這個問題沒有辦法得到比他給我的信息更好的回答,所以我把他的回答標爲正確。

我應該試睡更v.v