6

I was messing around with Express JS and was the using express-session. It didn't work if I didn't put the app.use(session()) middleware first

app.use(session({
     name: 'server-session-cookie-id',
     secret: 'my express secret',
     saveUninitialized: true,
     resave: true
}));
app.use('/', routes);
app.set("view engine", "pug");
app.set("views", path.join(__dirname + "/views"));
app.use(flash());

If the app.use(session()) written first it would say that the req.session.someVariablewas undefined.

Can someone explain how Express calls the app.use middleware?

kydCoco
  • 127
  • 1
  • 7

2 Answers2

10

All Express route handlers (whether app.use(), app.get(), app.post() or anything else) are checked for a route match in the order they are registered. Further, once a route sends a request and does not call next(), then no further routes are checked for a match to the current request. All processing for that request will be done.

So, you HAVE to put any middleware BEFORE any requests that want to use the results of that middleware.

Some people think that all app.use() handlers might be checked for a match and potentially executed (if they match the request) before any app.get() or app.post() handlers. That is not the case. There's a single handler order in the order they are registered, regardless of which type of handler it is.

It didn't work if I didn't put the app.use(session()) middleware first.

If the session middleware isn't before a request handler that wants to use the session, then the session variables won't yet be initialized when that request handler runs and req.session itself will be undefined.

You have to place the session middleware before any request handler that wants to use the session variables.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
2

In a testing environment, as a pure hack, you can inject middleware at the beginning and bypass the ordering during the initialization.

app.use(function test(req, res, next) { next() })
app._router.stack.splice(0, 0, app._router.stack.find(r => r.name === 'test'))
Mihailoff
  • 577
  • 5
  • 6
  • This really helped me - I was able to remove the compression middleware from the router stack. The compression middleware was preventing my server sent events from working when running in the web development server with ReactScripts. The ReactScripts turns on compress with no way to turn it off - Thank you! – mdebeus Oct 09 '21 at 03:43
  • Does this still work? I keep getting an error that layer.match is not a function. – Nehemiah Dec 22 '22 at 18:53