Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using cookieParser() and cookieSession() together?

cookieParser() gives us the option of signing cookies with a secret sentence, which is great to prevent tampering. I understand that a cookie is signed with a special value, to prevent tampering.

I just discovered cookieSession(), which I find to be a great alternative to server-stored cookies (I only store { loggedIn = true, userId=763487246824632}, it never grows).

But... I found that setting a "secret" for cookieParser() breaks things, and cookieSession() stops working if the secret sentence matches. The reason seems to be that if the cookie is signed using the same secret, then cookieParser() actually takes it and parses it. The strange thing is that once cookieParser() has done its work, and with the same signature secret, the session is set to:

{ cookie: 
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true } }

Rather than:

{ testing: 'OOO' }

(Each reload adds an 'o') So...

  • Did my analysis get it right?
  • Do you know why the session is set to that strange { cookie object if the secret sentences match?

Merc.

like image 701
Merc Avatar asked May 10 '13 04:05

Merc


People also ask

Do you need cookie-parser with Express session?

Since version 1.5. 0, the cookie-parser middleware no longer needs to be used for this module to work. This module now directly reads and writes cookies on req/res. Using cookie-parser may result in issues if the secret is not the same between this module and cookie-parser .

What is the difference between Express session and cookie session?

Cookie session is basically used for lightweight session applications where the session data is stored in a cookie but within the client [browser], whereas, Express Session stores just a mere session identifier within a cookie in the client end, whilst storing the session data entirely on the server.

How do I use cookies and sessions in node JS?

Cookies and sessions make the HTTP protocol stateful protocol. Session cookies: Session cookies are the temporary cookies that mainly generated on the server-side. The main use of these cookies to track all the request information that has been made by the client overall particular session.

Which property is used to set expiration time of cookies in Express JS?

So, to set expire time to cookies, an object with expire property can be sent which holds the expire time in milliseconds. An alternate approach to set cookie expiration age is to use optional magAge property. res. cookie(name, 'value', {maxAge : 9999});


1 Answers

Your analysis is correct, I can reproduce it.

The issue is caused by this line in the cookieSession middleware (some context: options.secret is the key passed to cookieSession, req.secret is the key passed to cookieParser): if you pass both middleware a secret key, cookieSession assumes that it will find the raw (unparsed) cookie in req.cookies.

But since cookieParser has picked up the signed cookie as well (and it's being run before cookieSession), it has parsed the cookie itself (and because the signing keys were the same, it succeeded to do so), stored it in req.signedCookies and deleted it from req.cookies. So as far as cookieSession is concerned, the cookie just isn't set.

The object you see is the default session contents (which is the cookie property from the cookieSession configuration):

app.use(express.cookieSession({
  cookie : { // <-- this object
    ...
  }
});

As for a solution: either use a different key for each middleware, or just pass one of them your secret key, but not both (with the understanding that if you pass it to cookieParser, all your cookies will be signed).

FWIW: I'm not entirely sure if this is a real bug. It's a consequence of using the same signing mechanism for both cookieParser and cookieSession, with no distinction between cookies signed by one or the other. Although it could be fixed by always checking if the cookie is located in req.signedCookies.

like image 79
robertklep Avatar answered Sep 21 '22 17:09

robertklep