23

I have an Express application with some routes, only two of them need to support sessions. I read everywhere that the middleware definition (app.use(express.session({...) applies only to the routes that comes after it, so I created this sample:

var express = require('express');
var app = express();
app.use(express.bodyParser());

app.get('/path1', function (req, res) {
    res.send('text response');
});


app.use(express.cookieParser());
app.use(express.session({
    secret: 'secret',
    cookie: { maxAge: new Date(Date.now() + 2 * 60 * 1000) }
}));


app.get('/path2', function (req, res) {
    res.session.test = { "test": "test" };
    res.send('text response');
});

app.listen(8088);

But this doesn't work: in /path2 res.session is undefined.
If I move the session middleware definition up - everything works, but I see that sessions are being create when calling /path1 (this is what I want to avoid)

Can someone explain how a single application can use session in only some of the routes.

Thanks!

///// UPDATE //////

After more digging - I figured it out:

Don't use: app.use(express.session({ ... }));
Instead - define the following:

var sessionMiddleware = express.session({
    //session configurations
});

function sessionHandler(req, res, next) { sessionMiddleware(req, res, next); }

Then apply the handler on the specific route/s that need session support:

app.get('/path_that_need_session', sessionHandler, function (req, res) {                     
 /* Do somthing with req.session */  
});
alonkad
  • 345
  • 1
  • 2
  • 9
  • 2
    To make your answer more clear, why not write it as an answer and accept it (it's OK). This worked really well for me to isolate sessions to certain routes. Thanks. – Shane Stillwell Jun 06 '13 at 18:45

2 Answers2

31

Don't use app.use(express.session({ ... })).

Instead, initialize the session middleware, save a reference to the resulting function then include it directly in the routes you want it on.

var express = require('express'),
    app = express();

var session = express.session({
    //session configuration
});

app.use(app.router);


// must come after app.use(app.router);
app.get('/your/route/here', session, function(req, res){
    // code for route handler goes here
});

Slightly simpler than the answer included in the update (you don't need the wrapper function).

Waylon Flinn
  • 19,969
  • 15
  • 70
  • 72
1

The problem is actually your route for /path1, which is defined before express.session is being used.

When you declare a route handler in Express, at that moment the router middleware (which handles all routes) will get inserted into the middleware chain. That means that if you haven't yet app.use'd any middleware which will be used by future routes (like your handler for /path2), they will never get called when handling any route.

If you move your handler for /path1 to after app.use(express.session(...)), it will work without having to resort to tricks.

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • If I move the /path1 route to after `app.use(express.session(...))` - it will use sessions (that's what I wanted to avoid). – alonkad Apr 09 '13 at 07:16
  • I wanted only /path2 to use sessions (it's only used for first time authentication). /path1 is more extensively used and doesn't need sessions - so I wanted to save sessions overhead (I save them in a DB) – alonkad Apr 09 '13 at 07:23
  • Fair enough. I think you can actually leave out the `sessionHandler` function in your case, because all that does is delegate the arguments to `sessionMiddleware` (so you might as well use that directly). – robertklep Apr 09 '13 at 07:30