30

I am just starting to learn how to use cookies with node and express and I would like some help with getting this to work. I tried to follow the expressjs/session tutorial on GitHub, however I am getting req.session as undefined, so I am unable to set or get any values.

My goal is to save the first and last name of a user to a cookie so that an input field will auto populate. I'm not sure if I need to use cookie-parser as well or if express-session can handle that alone. I'm not sure of how to proceed as I am new to cookies and express-session.

All help is appreciated! Thanks in advance.

Code

let express = require('express');
let app = express();
let credentials = require('../modules/credentials.js');
let session = require('express-session');
let sessionOptions = {
  secret: credentials.cookieSecret,
  cookie: {
    maxAge:269999999999
  },
  saveUninitialized: true,
  resave:true
};

if (app.get('env') === 'production') {
  app.set('trust proxy', 1);
  sessionOptions.cookie.secure = true;
}
else {
  sessionOptions.cookie.secure = false;
}

app.use(session(sessionOptions));
let router = express.Router();
app.use(router);

let request = require('request');
let db = require('../modules/queries');
let bodyParser = require('body-parser');
let cookieParser = require('cookie-parser');


// app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

router.get('/me', function(req, res, next) {
  console.log('req.session: '+req.session);

  let firstName = req.session.firstName;
  let lastName = req.session.lastName;
  if (firstName && lastName) {
    res.render('student/me.jade', {firstName, lastName});
  }
  else {
    res.render('student/me.jade', { firstName: '', lastName: ''});
  }
});

router.post('/api/me', function(req, res, next) {
  let firstName = req.body.firstName;
  let lastName = req.body.lastName;
  // session.firstName = firstName;
  // session.lastName = lastName;
  req.session.firstName = firstName;
  req.session.lastName = lastName;
  console.log('session.firstName: '+session.firstName);
  db.addEvent(req, res, next);
});

module.exports = router;
Ron I
  • 4,090
  • 8
  • 33
  • 64

5 Answers5

76

Once you mount a router onto an Express app, any subsequently declared middleware on that app won't get called for any requests that target the router.

So if you have this:

app.use(router)
app.use(session(...));

The session middleware won't get called for any requests that get handled by router (even if you declare the routes that the router should handle at some later point). For that, you need to change the order:

app.use(session(...));
app.use(router);

An additional issue is that you're exporting router, which should probably be app (which is the instance that "holds" all the middleware, routers, etc):

module.exports = app;
robertklep
  • 198,204
  • 35
  • 394
  • 381
  • Thanks @robertklep - I made the switch. It didn't resolve the issue, but that's helpful to know going forward! – Ron I Sep 30 '16 at 17:02
  • 1
    @RonI `req.session` being undefined is a sign that the session middleware isn't getting called (otherwise, it would populate `req.session` with an empty object). Can you show (in your question) how you add routes/middleware to your app? – robertklep Sep 30 '16 at 17:04
  • @RonI did you create your project using `express-generator`? – robertklep Sep 30 '16 at 17:19
  • @RonI see my edit about exporting `app` instead of `router`. – robertklep Sep 30 '16 at 17:45
  • nice! I didn't see the edit about export app, I made the change and it now works! Thanks :) – Ron I Sep 30 '16 at 17:47
7

To get session data

first , You have to initialize express-session with

app.use(session({ resave: true ,secret: '123456' , saveUninitialized: true}));

then When you want to put something in the session

req.session.firstName = 'Aniruddha';
req.session.lastName = 'Chakraborty';

Then you can check without errors

console.log('req.session: '+req.session.firstName);

Note: This is express-sessions work!

Aniruddha Chakraborty
  • 1,849
  • 1
  • 20
  • 32
6

This problem occurred with me while trying to maintain req.session object in my app. I was setting req.session.user in a login route, but was not able to get the same outside that route.

console.log(req.session) 
// undefined

Since there was no use of cookie in my app, I removed it.

Before removing cookie variable:

app.use(
session({
    resave: false,
    saveUninitialized: true,
    secret: "anyrandomstring",
    cookie: { secure: true},
  })
);

After removing cookie variable:

app.use(
session({
    resave: false,
    saveUninitialized: true,
    secret: "anyrandomstring",
  })
);

This resolved my issue. And now I was able to access req.session from anywhere in the app.

console.log(req.session)
/* Session{
     ......
     ......
    }
*/

Note: This issue might also occurs if you have initialized app.use(session({...})) at bottom of the file. Try to bring it to the top.

Why this happens: Click here

Deepam Gupta
  • 2,374
  • 1
  • 30
  • 33
1

You will also see req.session === undefined if your Redis connection is invalid or missing!

I don't see anywhere in your code where connection info is being passed when configuring the session.

Jordan Dodson
  • 415
  • 5
  • 5
1

Another reason why this might happen is if you're making requests from a different URL. Make sure your app is running on the same URL as your Express back-end.

tomasantunes
  • 814
  • 2
  • 11
  • 23
  • 1
    oh my god, thank you. I was going mad for hours what was going on. This helped it for me. – artSir Jul 16 '23 at 15:48