Search code examples
javascriptnode.jsexpresssessionws

Assigning account to a web socket connection


I'm building a website where you can play a card game and I need to make sure, that a web socket connection is coming from a user. I'm using express-session, connect-mongo, express and ws packages and I'm having trouble getting the session.

Parsing session on upgrade

server.on('upgrade', function (request, socket, head) {
  console.log('Parsing session from request...');

  session(request, {}, () => {

    console.log('Session is parsed!');

    wss.server.handleUpgrade(request, socket, head, function (ws) {
      wss.server.emit('connection', ws, request);
    });
  });
});

express-session

module.exports = session({
  secret: "HOPEFULLY-NO-ONE-FINDS-THIS!!!!",
  store: new MongoStore({ mongooseConnection: mongoose.db }),
  cookie: { secure: false }
})

Creating ws server
var wss = new WebSocket.Server({ noServer: true });

Saving to a session

router.post('/login', function(req, res, next) {
    const { username, password } = req.body;
    user.authUser(username, password, (err, user) =>{
        if (err) return res.send("Error on login!");
        req.session.user = user;
        res.redirect("/")
    });
});

On the client side I connect to my ws server with simple
new WebSocket('ws://localhost:3000');

This code was pretty much copied from here, but it doesn't work for me. When I try to log the session like this

wss.on('connection', function connection(ws, req) {
        console.log(req.session);
}

I only get

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

I'm pretty much stuck here. Is this even the correct way to do this? Thanks in advance!


Solution

  • So browsers only send cookies with websocket handshake when the domain is the same as the current website. I though this isn't a problem in my case, but it turns out that localhost and 127.0.0.1 isn't the same thing. Turning new WebSocket('ws://localhost:3000'); into new WebSocket('ws://127.0.0.1:3000'); fixes the issue.