AndrewHenderson
AndrewHenderson

Reputation: 4972

Use Express' Connect-Redis to store sessions on remote Redis server

I've been building an Express app in conjunction with Couch and Redis locally. It has been working fine.

I'm now seeking to use a remote Redis server hosted on Iris Redis. I've tried for days now but can't seem to get Express' Connect-redis to return a cookie after authenticating with Passport's local strategy. This is working just fine however when I have a local Redis server running.

app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use('/upload', upload.fileHandler());
app.use(express.bodyParser({ keepExtensions: true, uploadDir: 'public/uploads' }));
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({ cookie: { maxAge: 60000000 }, secret: "sauce", store: new RedisStore({
  port: 6379,
  host: 'url',
  pass: 'sauce'
}) }));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

});


// Authentication
passport.use(new LocalStrategy(function(username, password, done) {

username = username.toLowerCase();
db.get(username, function (err, doc) {

  if (err) {
    console.log(err);
    return done(err); 
  }
  if (!doc) {
    return done(null, false, { message: 'No user by that name.' });
  }
  if ( doc.password !== password ) {
    return done(null, false, { message: 'Incorrect password.' });
  }
    return done(null, doc);
  });

  })
);

passport.serializeUser(function (user, done) {
  done(null, user._id);
});

passport.deserializeUser(function (userId, done) {
   db.get(userId, function(err, user){
    if(err){
      return (500, err);
    } else {                                   
  done(null, _.omit(user, ["password"]));
    }
  });
});

// Route
exports.authenticate = passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login'
});

Upvotes: 2

Views: 2316

Answers (1)

Dan Kohn
Dan Kohn

Reputation: 34337

You don't seem to be specifying the redis db; that could be the cause of the failure.

More generally, I recommend using a URL in an environment variable to store the redis parameters, and therefore having the same parsing code whether you're connecting to a local or remote server. For example, from app.js:

var config = require('./config/config.js')

app.use(express.session({
    store: new RedisStore({
        port: config.redisPort,
        host: config.redisHost,
        db: config.redisDatabase,
        pass: config.redisPassword}),
    secret: 'pick a good password',
    proxy: true,  // necessary if you're behind a proxy
    cookie: { secure: true }
}))

And config.js:

var url = require('url')
var config = {};
var redisUrl;

if (typeof(process.env.REDISTOGO_URL) != 'undefined') {
    redisUrl = url.parse(process.env.REDISTOGO_URL);
}
else redisUrl = url.parse('redis://:@127.0.0.1:6379/0');

config.redisProtocol = redisUrl.protocol.substr(0, redisUrl.protocol.length - 1); // Remove trailing ':'
config.redisUsername = redisUrl.auth.split(':')[0];
config.redisPassword = redisUrl.auth.split(':')[1];
config.redisHost = redisUrl.hostname;
config.redisPort = redisUrl.port;
config.redisDatabase = redisUrl.path.substring(1);

console.log('Using Redis store ' + config.redisDatabase)

module.exports = config;

Upvotes: 1

Related Questions