1

I'm using express and node to host a server. I also have socket io where I'm trying to keep track of the user by saving their socket.id. However, I have two pages to the webapp, one to login and one for the actual content.

app.get("/", function(req, res) {
    res.sendFile(__dirname + "/login.html")
})

app.get("/content", function(req, res){
    res.sendFile(__dirname + "/index.html");
})

In my login.html, I have to the user login and then on a click of a button, i set the window.location.href to link to the index.html. Since the client socket io is created in login.html and in the index.html; changing from login to index refreshes the instance, giving the user a new socket.id. How would I get around this and link the user who accessed login.html and then redirected to index.html as the same user?

Ducker Hughes
  • 11
  • 1
  • 2

3 Answers3

0

I would suggest sending an access token to the client when they successfully login, then they can store that in localStorage, or in a cookie; somewhere persistent between page loads.

Then when they load any other page, you send up the token up to authenticate the websocket connection. This has the added advantage of allowing you to secure your websocket connection in addition to identifying the user.

Here's a quick, very abbreviated example

/// Server

var users = {
  'asdf123': { id: 'asdf123', name: 'jack', userConnections: [] }, // user could have multiple pages open, track all sockets
  '123asdf': { id: '123asdf', name: 'jill', userConnections: [] },
};

function onLogin(req, res) {
  // do some database login
  var user = users[asdf123];
  var token = jsonwebtoken.sign({ userId: user.userId }, 'secret signing key');
  res.json({ token: token });
}

io.on('connection', function (socket) {
  socket.authenticated = false; // have they sent us a valid token yet
  socket.on('auth', function (token) { // client will explicitly send the token
    jsonwebtoken.verifyToken(token, function (err, decodedToken) {
      if (err) { // bad or expired token, disconnect them.
        socket.disconnect();
        return;
      }
      if (users[decodedToken.userId]) {
        users[decodedToken.userId].userConnections.push(socket);
        socket.authenticated = true;
      }
    });
  });
});

/// Client

var socket = io();
var savedToken = localStorage.getItem('token');

socket.on('connect', function () {
  socket.emit('auth', savedToken);
});
Kal_Torak
  • 2,532
  • 1
  • 21
  • 40
0

You should use session to save socket id, don't save id to client side

see more: https://www.npmjs.com/package/express-socket.io-session

Jolly Ut
  • 1
  • 1
0

it's basically impossible as explained in this stackoverflow post:

how to handle page reload in socket.io client chat applications

However, as mentioned in above answer you could either:

  • move the socketio connection script in index.html file
  • Handle the disconnect event on the server-side (unregister/delete user) so that it get naturally re-registered when index.html page reload
  • Store in Local/Session storage some ID that you save in your DB to relate to your user.
erwan
  • 887
  • 8
  • 17