4

I'm using NodeJS + express + express-session to persist a userID from anywhere in the application.

On the first route, my session is defined

userProfileRoutes.route('/authentication').post((req, res) => {
  req.session.userID = 10; //example
  console.log(req.session)
}

The result of the console.log is:

Session {
  cookie:
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true,
     secure: true },
  userID: 10 } // this is the right value

But then, from a different route, I can't see the value:

userProfileRoutes.route('/edit').get(function (req, res) {
  console.log('After the nav edit route');
  console.log(req.session);
}

And this prints

Session {
  cookie:
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true,
     secure: true }
} // ID VARIABLE DISAPEARS HERE

I am configuring express-session using these parameters:

app.use(session({
  secret: 'secret',
  proxy: true,
  resave: false,
  saveUninitialized: true,
  withCredentials: true,
  cookie: { secure: true },
  store: new MongoStore({ mongooseConnection: db })
}));

Why is my userID not persisted between requests and on all routes?

lucascaro
  • 16,550
  • 4
  • 37
  • 47
  • did you try `cookie: { secure: true, maxAge: 600000 },` in `app.use` I am guessing the session expires immediately because maxAge is not mentioned. – Sumit Sahay Nov 09 '18 at 10:49
  • Indeed I tried, the problem is not with the session itself but with the variable userID it contains. I tried to console.log(req.sessionID) which is a defined value of the object session and it pops anywhere. The session is everywhere but the problem is the variable userID in it which is not... –  Nov 09 '18 at 11:05

1 Answers1

6

You are setting cookie: {secure: true} but trying to access your server using HTTP.

From the express-session documentation:

cookie.secure

Note be careful when setting this to true, as compliant clients will not send the cookie back to the server in the future if the browser does not have an HTTPS connection.

Please note that secure: true is a recommended option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If secure is set, and you access your site over HTTP, the cookie will not be set.

Make sure you are either using HTTPS (always in production!) or you set cookie.secure to false (maybe, and for development only!)

The secure flag in cookies

The secure flag is an option that can be set by the application server when sending a new cookie to the user within an HTTP Response. The purpose of the secure flag is to prevent cookies from being observed by unauthorized parties due to the transmission of a the cookie in clear text.

To accomplish this goal, browsers which support the secure flag will only send cookies with the secure flag when the request is going to a HTTPS page. Said in another way, the browser will not send a cookie with the secure flag set over an unencrypted HTTP request. By setting the secure flag, the browser will prevent the transmission of a cookie over an unencrypted channel.

from https://www.owasp.org/index.php/SecureFlag

Cookies in express-session

Following common practice, express-session uses cookies to store a session ID and server side storage (mongoDB in your case) to store session data. If the browser does not send your session ID because it can't find a valid cookie, your server will assume there is no session, and save the user id on a new session on every request.

When you got to /authentication it will save the ID on a new session. When you try to read in in a different request, the session ID has changed and you have no value in userID.

lucascaro
  • 16,550
  • 4
  • 37
  • 47
  • Alright this explains a lot of things now. Just before you did post that, I was wondering why my sessionID stored in Mongo was different after each request, so its quite the same problem I had with the req.session.idUser. I tried to put {secure: false} in my cookie as you said, but the sessionID is still changing after another request. The problem is still with the "valid cookie" isnt it? Even with the {secure:false}, the browser doesnt find a valid cookie :/ Maybe i'm missing something, on other topics putting {secure:false} was enough to solve similar problems with sessions... Thanks Lucas –  Nov 14 '18 at 11:03
  • not sure what you mean by the user id changing, in the example it would always be 10, are you setting a random id? – lucascaro Nov 14 '18 at 20:27
  • The ID changing is the session one (req.sessionID or req.session.id, automatically assigned by the server). You are right my user Id shouldn't change over navigation, because its the id I'm fetching from database for a user. But I cant keep it through pages because the req.sessionID is always changing after requests –  Nov 15 '18 at 08:39
  • sounds like there is some other bug in the code. It's hard to know without seeing the whole thing. This is personal now. Do you have a [mcve] with the error happening? – lucascaro Nov 16 '18 at 17:30