0

I'm trying to use express-session but it is not working the way I want. For example, if I visit http://127.0.0.1:8081/test from browser 3 times, I see following response in browser:

Not set

Already set

Already set

The means seesionID for is unique and session is not destroyed when I visit this page again and again.

However, the scenario changes when I request the same page using Ajax, which I have wrote in test.php file:

test.php

<script type="text/javascript">
  $(document).ready(function(){
    setInterval(function(){
    $.ajax({
      type: 'get',
      url: 'http://127.0.0.1:8081/test',
      success: function(data){
        console.log(data);
      },
      error: function(aa, bb, cc){
                  // console.log("Ajax error", aa, bb, cc);
        }
      });
     }, 5000);
  });
</script>

Server side code:

var express = require('express');
var mysql = require('mysql');
var session = require('express-session');
// var MySQLStore = require('express-mysql-session')(session);
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json({type: '*/*'}));
var http = require('http');
app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    next();
});

var server=http.createServer(app);

app.use(session({
  secret: 'some secret',
  resave: false,
  // rolling: true,
  saveUninitialized: true,
  cookie: {
    secure: false,
    maxAge: 36000000,
    httpOnly: false,
  },
}));


app.get("/test", function(req, res, next){
     console.log(req.session);
  console.log(req.sessionID, req.session.name);
    if(!req.session.name){
        console.log("Not set.");
        res.write("Not set");
        req.session.name = "vikas kumar";
    } else {
        console.log("Already set");
        res.write("Already set");
        console.log(req.session.name);
    }
    res.end();
});

server.listen(8081, function(){
    var host = server.address().address;
    var port = server.address().port;
    console.log("testApp socket server is listening at http://%s:%s", host, port+"\n\n");
});

From this, I see following response in browser's console:

Not set

Not set Not set ... And so on.

Note: I'm not using default Memory Store for session.

Am I doing something wrong? Or it has something to do with Ajax request?

user3.14
  • 361
  • 1
  • 12
  • Is your ajax call going to the same host and port as the web page? Or is it a cross origin ajax request? – jfriend00 Jun 25 '17 at 16:34
  • Perhaps this [Cookies are not set from Cross domain AJAX request](https://stackoverflow.com/questions/32750507/cookies-are-not-set-from-cross-domain-ajax-request). – jfriend00 Jun 25 '17 at 16:40
  • It could also be that your browser is blocking third party cookies which a cross domain ajax request would be using. – jfriend00 Jun 25 '17 at 16:44
  • Here it is: I visit http://127.0.0.1/test/index.php and from there I make the above mentioned ajax call. The only difference in the URLs is PORT. Does this difference makes them cross domain request? @jfriend00 – user3.14 Jun 27 '17 at 11:54
  • Yes. a different port makes it a different origin which makes it a cross origin request. Here's how a same origin is described in [this article](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy). In a nutshell, to be the same origin, it must be the same protocol (e.g. http), same domain and same port. – jfriend00 Jun 27 '17 at 12:03
  • You're right. I followed this https://stackoverflow.com/questions/2870371/why-is-jquerys-ajax-method-not-sending-my-session-cookie and my issue is solved. But now I can't use * to allow more than one cross domain in headers as Chrome shows issue with it. Is there any way to handle 2-3 domains? – user3.14 Jun 27 '17 at 12:12
  • See [Access-Control-Allow-Origin Multiple Origin Domains?](https://stackoverflow.com/questions/1653308/access-control-allow-origin-multiple-origin-domains). – jfriend00 Jun 27 '17 at 12:19
  • Okay, one last thing: Would I always need to use this cross domain header because the port is different even the site (127.0.0.1) is same? For example if I buy AWS server and create a similar index page and start a server on some port? Is there any way that I don't need to use this header? One thing I guess is using the same PORTS. But how do I determine which PORT should I use? – user3.14 Jun 27 '17 at 12:37
  • I've already answered that in my previous comment. To be the same origin, it must be same host, same port and same protocol. Any one of those is different and it's cross origin and subject to security restrictions. A different port, even when the other aspects are the same causes it to be subject to cross origin restrictions. – jfriend00 Jun 27 '17 at 21:20
  • You should now finalize it as answer? – user3.14 Jun 28 '17 at 07:08

1 Answers1

0

It appears that you are making an ajax call to an origin that is not the same origin as the web page the code is in. That makes it a cross origin request (any request to a different domain, port or protocol is cross origin). A cross origin request seriously complicates cookie handling because those cookies become third party cookies which may be denied by the browser. Here's an article on MDN about same origin vs. cross origin.

To allow cookies on several cross origin domains, see Access-Control-Allow-Origin Multiple Origin Domains and Why is jquery's .ajax() method not sending my session cookie? and XMLHttpRequest.withCredentials.

The general idea is that you enable cross origin access from your server with credentials and then that instructs the browser that its ok to send cookies with that cross origin request.

jfriend00
  • 580,699
  • 78
  • 809
  • 825