20

I'm having fully functional user signup / authentication system using Express and Connect middleware.

app.use(express.session({store: require('connect').session.MemoryStore( {reapInterval: 60000 * 10} ) }))

The only problem is that sessions drop every time you perform server restart.

nodemon restarts Node.js every time it detects a file change.

How can I have persistent sessions?

user80805
  • 6,088
  • 5
  • 28
  • 31

5 Answers5

24

Like your code is telling you are using MemoryStore. This is volatile and gets cleared on restart. I would advise you to use connect_redis to persist your session. Redis is an extremely fast store.

  1. Download redis
  2. compile redis: make
  3. Start server: ./redis-server
  4. npm install connect-redis
  5.  

    var connect = require('connect') , RedisStore = require('connect-redis');
    
    connect.createServer(
      connect.cookieParser(),
      // 5 minutes
      connect.session({ store: new RedisStore })
    );
    

This is just to get you started quickly. You should read the documentation and configure redis if you want to get most out of redis.

Alfred
  • 60,935
  • 33
  • 147
  • 186
14

I was trying to get Redis on track using express.js, Google sent me here. The express implementation changed:

var express = require('express'),
RedisStore = require('connect-redis')(express);

Another important thing is the order of express configurations.

app.configure(function(){

    app.enable('strict routing'); // removes trailing slash
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jqtpl');
    app.register('.html', require('jqtpl').express);
    app.use(express.favicon());
    app.use(express.methodOverride());
    app.use(express.compiler({src: __dirname + '/public', enable: ['sass']}));
    app.use(express.static(__dirname + '/public'));
    app.use(app.router);
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({secret: _.config.secret, store: new RedisStore}));

});

cookieParser & session configurations need to be at the end of the configurations, and cookieParser must be placed right before express.session.

Hope that helps, I ran in both of these problems.

Wtower
  • 18,848
  • 11
  • 103
  • 80
ezmilhouse
  • 8,933
  • 7
  • 29
  • 38
8

I agree with everybody about Redis, but I think that different technologies are a problem in terms of software maintenance. If you are using MongoDB for example there is connect-mongo (https://npmjs.org/package/connect-mongo), if you are using MySQL there is connect-MySQL (https://npmjs.org/package/connect-mysql), connect-couchdb for CouchDB (https://npmjs.org/package/connect-couchdb) and so on.

Harsh Patel
  • 6,334
  • 10
  • 40
  • 73
6

also, if you're using express, you need to provide a secret when telling the app to use the redis middleware.

so, follow Alfred's recipe above, but do the following...

var express = require( 'express' );
var RedisStore = require('connect-redis');

app.use( express.cookieParser() );
app.use( express.session( { secret: "keyboard cat", store: new RedisStore }));
Meadhbh Oh
  • 61
  • 1
  • Now you need to add require('connect-redis')(express) - otherwise you get a TypeError: Cannot read property 'session' of undefined. (https://github.com/visionmedia/connect-redis/issues/24) – Christian Landgren Mar 12 '13 at 22:22
1

When node dies I would imagine the memory store you're using dies.

Persist the sessions to disk?

Richard Holland
  • 2,663
  • 2
  • 21
  • 35
  • 3
    as redis handles the session in an additional process the session survives node crashes and node restarts, if redis goes down, sessions go down accordingly – ezmilhouse Mar 05 '12 at 12:31