6

My express-session is working, I tested it with a very short cookie max-age (10 secs) and it works as intended:

app.use(session({
  secret: 'xxx',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true, maxAge: 10000 }
}));

The strange thing is, that I can't find the cookie anywhere in my Chrome Developer Tools. Where is the cookie set by express-session hidden?

update #2: See my own answer if you want to know where to see the cookie if you are sending an ajax request to an express server on another domain.

update - the session management on my express server:

app.post('/verify', function(req, res){
    let out = [];

    if(!req.session.userId){

        if(typeof req.body.token !== 'undefined'){
            admin.auth().verifyIdToken(req.body.token)
            .then(function(decodedToken) {
              let uid = decodedToken.uid;

              if(!req.session.userId){
                  req.session.userId = uid;
              }

              res.send(uid);
              // ...
            }).catch(function(error) {
              // Handle error
              res.send(error);
            });
        }else{
            res.send('no token received');
        }
    }else{
        res.send('already logged in by session with uid: ' + req.session.userId + ' | session id: ' + req.session.id);
    }
});

and that's how the server is "started":

app.listen(port, function () {
  console.log('Example app listening on port ' + port + '!');
});

the problem is that the session(s) work, but I am not able to see the cookie(s):

enter image description here

low_rents
  • 4,481
  • 3
  • 27
  • 55
  • It seems, you use a `http` server in your code. But as you can read in my answer, you **need** to use `https` if you use `cookie.secure`! Please verify your server setup to be sure or use a insecure cookie. – eisbehr Feb 05 '18 at 10:26
  • @eisbehr thank you, I'll try that - but why the hack do the sessions still work then? - that's what I don't get. – low_rents Feb 05 '18 at 10:28
  • Well, that belongs to what you mean with "it works". The sessions itself will work as expected. It can read and save data in session. The only thing is that storage of the cookie. You will loose the data directly after connection close. The fact that different browsers shows the same behavior is a indicatior that something is still wrong somewhere ... – eisbehr Feb 05 '18 at 10:33
  • @eisbehr yes, but to my knowledge the session can only get identified by the cookie, which doesn't seem to be there. – low_rents Feb 05 '18 at 10:49
  • Did you ever tested my example code in my answer? Is this working too and count up? – eisbehr Feb 05 '18 at 10:54
  • @eisbehr not yet - and I think I can't - because my node app is hosted on heroku - and I don't have SSL credentials. – low_rents Feb 05 '18 at 11:22
  • Just remove the credentials and start a http server and see if this works. Maybe exactly SSL is the issue here. Here's the script with just `http`: https://jsfiddle.net/dLy7oqmp/1/ – eisbehr Feb 05 '18 at 11:29
  • Forgot to disable `secure: true` in the `http` example. ;) Updated above. – eisbehr Feb 05 '18 at 11:31
  • @eisbehr sorry for the late answer - I also tried it with the `http` settings - and it did not change anything. heroku is `https` by default, so it will be still routed to `https` I guess. It's working, but the cookies still don't show up in the browser. – low_rents Feb 09 '18 at 10:49

2 Answers2

3

TL;DR

You can find the Cookie in the Chrome DevTools under:
Application > Storage > Cookies > URL of the express Server

Where to start

To show that the cookies of express are stored correctly, I've start with a simple test server. Note that you used cookie.secure = true in your question, which requires a https connection to the server. Otherwise, the cookie will be dropped immediately by the browsers. So let's use this simple one:

let fs = require('fs');

let privateKey  = fs.readFileSync('../../../apache/conf/ssl.key/server.key', 'utf8');
let certificate = fs.readFileSync('../../../apache/conf/ssl.crt/server.crt', 'utf8');
let credentials = {key: privateKey, cert: certificate};

let https = require('https');
let app = require('express')();
let session = require('express-session');

app.use(session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true,
    cookie: {secure: true, maxAge: 10000}
}));

app.all('*', function(req, res) {
    res.status(200);
    res.setHeader('Content-Type', 'text/html');

    if (!req.session.views) {
        req.session.views = 0;
    }

    req.session.views++;
    res.write('<p>views: ' + req.session.views + '</p>');
    res.end();
});

https.createServer(credentials, app).listen(8080);

When working correctly, you should be able to open https://localhost:8080 in your browser and see a content like views: 1.

When refreshing the browser, the count should be increased with every request. The max lifetime of the cookie without request is 10 seconds long. After this time, the count will start at 1 again.

Where to find the Cookie in the DevTools

Within the 10 seconds lifetime, you can see the cookie under Application > Storage > Cookies > URL of the express Server inside of the Chrome DevTools. The value of the cookie in this case is encrypted, of course.

Where to find cookie in Chrome DevTools

Some hints when using AJAX

As you mentioned later, your question belongs to AJAX calls. In general, it's all the same as above. You can see even AJAX created cookies instantly in the Storage > Cookies tab. But only, if your cookie is configured correctly and belongs to the same domain.

The cookies in the Storage tab are selected by the cookie domain and the cookie path. The list will be show and update everything that matches the pattern. So it seems, in your example, that the cookie don't match the requesting page.

As I saw on your page, you are opening the page with the ULR https://***.firebaseapp.com and do a AJAX request to https://***.herokuapp.com/verify/, which are two complete different domains. That's why you don't see them in the Storage tab!

If this will still not work, when using the same domain, set a cookie.path in your session configuration. Then everything should be work as described above. ;)

eisbehr
  • 12,243
  • 7
  • 38
  • 63
  • wow - thank you for your detailed answer! my sessions are working as expected - the "problem" or the "strange thing" is, that I still can't see them in developer tools. I see my domain there, but there is NO cookie set. – low_rents Feb 05 '18 at 10:03
  • The only way I know, that Chrome doesn't show cookies there, is whenever the page is blocked to save cookies. Then the behavior is like you descriped, it works in general, you see the domain but no session cookie. Maybe check your cookie settings in chrome or maybe test the same thing with firefox. Here's how to check your cookie settings: https://support.google.com/accounts/answer/61416?co=GENIE.Platform%3DDesktop&hl=en @low_rents – eisbehr Feb 05 '18 at 10:10
  • but when the page would be blocked, then my sessions wouldn't work at all, I assume.. but they do work. Also tried with firefox - can't see the cookie there neither. I will update my question with a bit more of the express server's code. maybe that helps. – low_rents Feb 05 '18 at 10:18
  • sorry for the late reaction - but this is just my "hobby project", so I can't work on it 24/7. If I set the cookie domain to `https://***.firebaseapp.com` and the cookie path to `/` it still doesn't work - even worse - the session behavior doesn't work at all. I also tried to set the domain without `https://` and without path - in each possible combination. – low_rents Feb 12 '18 at 09:41
  • 1
    AFAIK you can't just change the cookie domain to another domain. The browsers will reject this as insecure, if the cookie domain and the real domain don't match. You need to change the request url or life with the fact, that you can't see the cookies in the storage tab. ;) @low_rents – eisbehr Feb 12 '18 at 09:47
  • okay, I see - have learned a lot about cookies by playing around with this and by you providing so much information. can you maybe add to your answer, that the cookies are not visible due to the foreign domain? and my own answer shows where you can see them in that case. – low_rents Feb 12 '18 at 09:51
1

My question was missing some important information as I now have found out.
What I did not mention is, that the request is send via ajax.
In Chrome (and I guess in most browsers) you don't see those "connection cookies" where the "site" cookies are shown. you see them in the connection tab under the detailed information of the ajax request.

enter image description here

low_rents
  • 4,481
  • 3
  • 27
  • 55
  • Your answer is only half the truth. It has nothing to do with AJAX in general. Plese see my updated answer for your problem ... – eisbehr Feb 09 '18 at 12:24