Sven
Sven

Reputation: 5265

connect-redis and express-session results in req.session undefined

I'm trying to get express-session to store the session in Redis, but it doesn't seem like it wants to save. When I revert back to default session store it works flawlessly. The Redis daemon is hosted on a Vagrant VM with default configuration, and the app is able to connect to it, although it doesn't want to save sessions to it.

Here's my code:

var express = require('express');
var glob = require('glob');

var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var compress = require('compression');
var methodOverride = require('method-override');
var session = require('express-session');
var passport = require('passport');
var redis = require('redis');
var RedisStore = require('connect-redis')(session);
var auth = require('./passport');
var flash = require('connect-flash');

module.exports = function(app, config) {
  app.set('views', config.root + '/app/views');
  app.set('view engine', 'jade');

  // app.use(favicon(config.root + '/public/img/favicon.ico'));
  app.use(logger('dev'));
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({
    extended: true
  }));
  app.use(cookieParser());
  app.use(session({ 
    store: new RedisStore({ 
      host: config.redis.host,
      port: config.redis.port
    }),
    secret: config.secret, 
    saveUninitialized: true,
    resave: false 
  }));
  /*app.use(session({
    secret: config.secret,
    saveUninitialized: true,
    resave: true
  }));*/
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(flash());
  app.use(compress());
  app.use(express.static(config.root + '/public'));
  app.use(methodOverride());

  var controllers = glob.sync(config.root + '/app/controllers/*.js');
  controllers.forEach(function (controller) {
    require(controller)(app);
  });

  app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
  });

  if(app.get('env') === 'development'){
    app.use(function (err, req, res, next) {
      res.status(err.status || 500);
      res.render('error', {
        message: err.message,
        error: err,
        title: 'error'
      });
    });
  }

  app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: {},
      title: 'error'
    });
  });

};

As you can see, I got the default one commented out, and if I remove those comments and comment out the redis store, it works as it should. Any clues why this is happening? I'm not getting a single error.

Upvotes: 2

Views: 5033

Answers (1)

lukaszfiszer
lukaszfiszer

Reputation: 2631

You probably have some connection errors, but connect-redis does not output them to console (see connect-redis source code). To see them you can create a separate module that creates a client instance and pass it to RedisStore constructor:

// redisClient.js
var redis = require('redis');

var redisClient = redis.createClient('localhost', 6379); // replace with your config

redisClient.on('error', function(err) {
     console.log('Redis error: ' + err);
}); 

module.exports = redisClient;

Redis client emits also other event that may be helpful in debugging - see node-redis docs

// your code
var redisClient = require('./redisClient.js`);

(...)

app.use(session({ 
    store: new RedisStore({ 
        client: redisClient
    }),
    secret: config.secret, 
    saveUninitialized: true,
    resave: false 
}));

Upvotes: 4

Related Questions