akio
akio

Reputation: 1021

express-session won't set cookie connect.sid

EDIT 5

I have back and front end running on LAMP environment accesible with 192.168.80.213/backend adress. I try to make a push notification server using nodejs, socket.io and express framework to link back and front end.

My nodejs server is listening on port 3000 while my backend and front end listenning on port 80 both using apache.

Here is my node client :

<script type="text/javascript" src="socket.io-1.4.5.js"></script>
<script type="text/javascript">
    var socket = io('http://192.168.80.213:3000/');
</script>

Here is my node server :

const   express          = require('express')
        , app            = express()
        , http           = require('http').Server(app)
        , socketIo       = require('socket.io')(http)
        , cookieParser   = require('cookie-parser')
        , cookie         = require('cookie')
        , connect        = require('connect')
        , expressSession = require('express-session')
        , port           = 3000
        , helmet         = require('helmet')
        , name           = 'connect.sid'
        , sessionStore   = new expressSession.MemoryStore({ reapInterval: 60000 * 10 })
        , sessionSecret  = 'VH6cJa7yZSmkRbmjZW#J3%CDn%dt'
        , environment    = process.env.NODE_ENV || 'development'
        ;

/** Configuration **/
app.enable('trust proxy');
app.disable('x-powered-by');
app.use(helmet());
app.use(cookieParser());
app.use(expressSession({
    'name'  : name,
    'secret': sessionSecret,
    'store' : sessionStore,
    'resave': true,
    'saveUninitialized': true
}));

app.get('/', function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello from node');
});

socketIo.use(function(socket, callback) {
    // Read cookies from handshake headers
    var cookies = cookie.parse(socket.handshake.headers.cookie);
    // We're now able to retrieve session ID
    var sessionID;
    if (cookies[name]) {
        console.log( "cookies['" + name + "'] = " + cookies[name] );
        sessionID = cookieParser.signedCookie( cookies[name], sessionSecret );
        console.log( "sessionID = " + sessionID );
    }else{
        console.log( "cookies['" + name + "'] = undefined" );
    }

    if (!sessionID) {
        console.log('ERROR NO SESSION CONNECTION REFUSED !!');
        callback('No session', false);
    } else {
        // Store session ID in handshake data, we'll use it later to associate
        // session with open sockets
        socket.handshake.sessionID = sessionID;
        callback(null, true);
    }

});


socketIo.on('connection', function (socket) { // New client
    console.log( 'new connection..' );
    console.log('user ' + socket.handshake.sessionID + ' authenticated and is now connected.');  

});

/** Start server */
http.listen(port);
console.log( "listening on :" + port );

Go to 192.168.80.213:3000 and see 'Hello from node' and cookie['connect.sid'] is set according to screenshot below

connect.sid cookie correctly set

And console output :

enter image description here

Now Clearing cache and i'm going to my back end app where is my nodeClient 192.168.80.213/backend.

connect.sid cookie doesn't exist

enter image description here

And console output :

enter image description here

Why express-session ain't set cookie.sid ? how can i fix that ? I'm new to node and express, i spend many times googling without succes, hope some node masters coul help me !!

regards

Upvotes: 1

Views: 7912

Answers (2)

Spencel
Spencel

Reputation: 80

I don't have experience using cookie or cookie-parser and am generally new to node, but I had a similar system to authenticate socket connections by accessing server side session variables if that helps at all.

Save the session details inside a variable

var sessionStorage = expressSession({
'secret': sessionSecret,
'store' : sessionStore,
'resave': true,
'saveUninitialized': true 
});

let socketIo and app use the storage

socketIo.use(function (socket, next) {
    sessionStorage(socket.request, socket.request.res, next);
});
app.use(sessionStorage);

and then inside on connect you can access those session variables using:

socket.request.res.session.[variable name]

Upvotes: 1

dNitro
dNitro

Reputation: 5345

I dont know which version of socket.io you are using but after version 1.0 (> 1.0):

  • To register a middleware you should use socketIo.use (See documentation)
  • First parameter is incoming socket which have access to request through socket.request
  • express session by default save cookies with connect.sid name if you want to use io name you should set it explicitely (See name option)
  • When you want to parse a signed cookie you should provide it sessionSecret not sessionStore
  • and finally i think handshake support is deprecated and you should attach anything you want directly to socket (See authentication-differences).

With considering aboves you could use a middleware like following to Authenticate your sockets:

// every incoming socket should pass this middleware
socketIo.use(function(socket, next) {
  var cookies = cookie.parse(socket.request.headers.cookie);
  var sessionID = cookieParser.signedCookie(cookies['connect.sid'], sessionSecret);
  sessionStore.get(sessionID, function(err, session) {
    if ( session && session.isAuthenticated ) {
      socket.userId = session.user.id;
      return next();
    } else {
      return next(new Error('Not Authenticated'));
    }
  });
});
// when connected ...
socketIo.on('connection', function(socket) {
  console.log('user ' + socket.userId + ' authenticated and is now connected.')
});

Here i consider you set isAuthenticated Boolean value and user on session when users logged in.

Also bear in mind that built in sessionStore, MemoryStore is not suit for production environment:

The default server-side session storage, MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.

So you must consider using another session store like:

Upvotes: 1

Related Questions