3

I'm working with expressjs and want to authenticate users for a login using sessions. The site/app should on one hand allow the user to browse and investigate different products and information in a stateless webpage allowing caching of these pages, but should on the other hand have the functionality to let the user login and access different content acquired using sessions.

Thus for a subset of my routes I want session state activated, while for the complementary subset (the rest of my routes) express sessions should be deactivated, allowing caching of these pages.

How can I do this in a clean way?

Say the routes for which I want to activate sessions are '/kj%C3%B8p', '/bibliotek' and '/register'.

I tried something like

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');

  var pageName = 'somepage';
  var oneYear = 1000*60*60*24*365;
  app.use(express.bodyParser());
  app.use('/kj%C3%B8p', express.cookieParser());
  app.use('/kj%C3%B8p', express.session({key: pageName, secret: 'someCode', store: new RedisStore, cookie: {path:'/', maxAge: (5*oneYear), httpOnly: true}}));
  app.use('/bibliotek', express.cookieParser());
  app.use('/bibliotek', express.session({key: pageName, secret: 'someCode', store: new RedisStore, cookie: {path: '/', maxAge: (5*oneYear), httpOnly: true}}));
  app.use('/registrer', express.cookieParser());
  app.use('/registrer', express.session({key: pageName, secret: 'someCode', store: new RedisStore, cookie: {path:'/', maxAge: (5*oneYear), httpOnly: true}}));

  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));

});

but this regenerates the session object for each of the three routes, and seems quite messy. Any tips?

torgebo
  • 31
  • 3

1 Answers1

5

You can wrap middleware in a function to black or whitelist certain urls. This is a whitelist example:

function allow(paths, fn) {
  return function(req, res, next) {
    if (~paths.indexOf(req.url)) {
      return fn(req, res, next);
    }
    next();
  }
}

You wrap it around your middleware like:

app.use(allow(['/bibliotek', '/registrer'], express.cookieParser()));

You can use the same technique for other middleware as well. This was based on a gist that the express author showed in irc.

Pickels
  • 33,902
  • 26
  • 118
  • 178
  • There seems to be some practical issues with this approach: -using the deny function does not seem to work because other sources on the page also calls the app.use (for example images on the page calls on app.use. Hence using deny one would have to specify these too.) – torgebo Aug 07 '12 at 11:16
  • - The 'allow' function works with the mentioned routes. But if I want to match a route like '/bibliotek/:id' then there seems to be no regexp support in app.use. The solution here seems to be to manually add the regexp and instead compare req.url with the regexp in allow. It would be nice to do this comparison automatically with res.app.routes, but this seems to be undefined at application start so rewriting allow to use these automatically gives some nasty errors. – torgebo Aug 07 '12 at 11:16
  • The allow function is just a function that wraps middleware which is also just a function. If you need regex matching on urls then use regexes. – Pickels Aug 07 '12 at 12:30
  • @torgebo did you ever find a solution to this? I want to match routes within middleware (avoiding having to use the `get/post` directive). I just want to `use` my custom middleware and match the path from within, but Express doesn't seem to expose its routing logic. – shennan Jun 23 '13 at 14:25