Authorizing and handshaking with Socket.IO

Since Socket.io 1.0 , Although there is backwards compatibility it is recommended to use "io.use()" in order to add your ad-hoc middleware, so in the Node Server side:

io.use(function(socket, next){
  var joinServerParameters = JSON.parse(socket.handshake.query.joinServerParameters);
  if (joinServerParameters.token == "xxx" ){
    next();          
  } else {
    //next(new Error('Authentication error'));                  
  }
  return;       
});

And on the client side, to add your own attribute to the handshake, it would look like this:

var joinServerParameters = { token: "xxx"   };    
var socket = io.connect('url' , {query: 'joinServerParameters=' + JSON.stringify(joinServerParameters)  });

Edit: In Socket.IO 1.0, middleware is now used. Authorization can be done like so:

io.use(function(socket, next) {
  var handshake = socket.request;
  next();
});

If you were to need to reject the socket, just pass an error object to the next() callback. The same thing can be done with namespaces:

io.of('/namespace').use(function(socket, next) {
  var handshake = socket.request;
  next();
});

Authorization in Socket.IO is run through a function which is decided in a boolean that is passed by a callback. This function runs every time a connection attempts a handshake, and this is what it looks like:

io.set('authorization', function (handshake, callback) {
  callback(null, true);
});

The function callback() accepts two parameters. The first is the error reason, if any, and the second parameter is the boolean that decides if a client may connect or not. By default there is no authorization, so the scenario is shown in the code sample above, where the socket that is connecting is allowed passage with true.

The handshake in Socket.IO is like any other information technology related handshake. It is the process of negotiation, which in Socket.IO's case, decides whether a client may connect, and if not, denies the connection. The handshake is initiated with either a XHR or JSONP request, and doesn't do much when no authorization is specified, but can be helpful in the data passed in the handshake data object.

To answer your last question, yes, you may add anything into the handshake object. The object is the same variable reference to the socket.handshake object, which allows you to do things like this:

io.set('authorization', function (handshake, callback) {
  handshake.foo = 'bar';
  callback(null, true);
});

io.sockets.on('connection', function(socket) {
  console.log(socket.handshake.foo); // bar
});

This is very useful, because you can store socket-based properties. A common use for this is with the Express framework, where one can identify the session ID based on the cookies passed by Socket.IO, which then a matching session can be identified.


Right now i'm using this simple method:

io.set('authorization', function (handshakeData, accept) {
  var domain = handshakeData.headers.referer.replace('http://','').replace('https://','').split(/[/?#]/)[0];
  if('myDomain.com'==domain)
    accept(null, true);
  else 
    return accept('Deny', false);
});