Nodejs: Express + 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 е недефиниран. Браузърът изпраща правилната страна.

Не съм експерт по точния поток, който възниква по време на заявката, но след отстраняване на грешки изглежда, че рутерът е бил извикан преди мидълуера на сесията.

Благодаря предварително за евентуалната помощ. Ще осигуря всеки код, който мога, не съм сигурен какво може да ви помогне.

Ето още код. 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 различни файла (някак си нямах нужда от сесия досега, тъй като забавях някои части и всичко необходимо беше направено с Mongoose). Ето пример как се прави (с фалшиви имена):

routes/index.js

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

routes/settings.js

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

Ето изтрит файл "route1" ("routes/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!")
}

person Mamsaac    schedule 03.10.2012    source източник
comment
имате този ред там два пъти: app.use(express.session({ store : session_store, secret : SESSION_SECRET, key : sid }));   -  person chovy    schedule 03.10.2012
comment
Грешка, поставих кода два пъти (всички редове бяха два пъти там)   -  person Mamsaac    schedule 03.10.2012
comment
това оправи ли проблема? Не виждам къде използвате req.session   -  person chovy    schedule 04.10.2012
comment
не, това се случи, когато поставих кода тук (никога не съм имал това двойно в моя код). Ще дам пример за това как req.session е недефиниран.   -  person Mamsaac    schedule 04.10.2012
comment
можете ли да публикувате целия си файл server.js?   -  person c0deNinja    schedule 04.10.2012
comment
Просто го добавих. Надяваме се, че това служи за определена цел.   -  person Mamsaac    schedule 04.10.2012


Отговори (2)


Всеки път, когато дефинирате маршрут, рутерът автоматично се вмъква в какъвто и да е стек на мидълуера по това време (последващи опити за умишлено вмъкване ще бъдат игнорирани). Сигурни ли сте, че не дефинирате никакви маршрути, преди да зададете манипулатора на сесия?

person ebohlman    schedule 03.10.2012
comment
да Това е идея, която обиколи ума ми... Така че сложих console.log точно преди и след добавяне на мидълуер на сесията, а също и преди и след добавяне на маршрути и изходът идва първо за сесията (но преди и след добавяне) и след това за маршрути . Възможно ли е редът на мидълуера да бъде нулиран от някакво мое действие? - person Mamsaac; 04.10.2012
comment
Можете да опитате да преместите вашето извикване на static след извикването на router. Не съм запознат с i18next, така че не знам дали това може да е причина за проблема. Можете също да опитате да преместите errorhandler в края на стека; възможно е там, където е сега, да липсва грешка, произхождаща от session. - person ebohlman; 04.10.2012
comment
Коментирах i18next и errorhandler, без да бъдат коригирани. Преместих статиката под app.router (забележете, че деактивирам статиката за производство, тъй като използвам nginx за това) и пак не помогна. Все още мисля, че си на прав път, но не съм сигурен къде се прецаках :( - person Mamsaac; 04.10.2012

Забравих да актуализирам това: Ebohlman ме постави на правилния път.

Следващият беше i18. Когато извиква един от методите init, той настройва маршрути и принуждава app.router да бъде принуден в стека на манипулатора по-рано. Лошото ми е, че не разбрах, че част от кода взаимодейства с обекта на приложението и това го направи. Нямаше начин въпросът да получи по-добър отговор от това как той се справи с информацията, която дадох, така че отбелязвам отговора му като правилен.

Трябва да опитам да спя повече v.v

person Mamsaac    schedule 04.10.2012