Socket.io 1.2.0: Handling global authorization events when client connects to a custom namespace

The documentation on socket.io’s page and its GitHub page are inconsistent (namely due to the latter being out of date, but contains information not covered by the former). A problem arises when using global authorization middleware on the server, having a client trying to connect to a custom namespace, and having the server deny access to the connecting client by passing an error to next() in the middleware.

Sample server authorization middleware code that denies access globally to all incoming connections:

io.use(function(socket, next) {
  next(new Error('not authorized'));
});

Sample client connecting code with error handler:

var socket = require('socket.io-client')('http://localhost/customnamespace');

socket.on('error', function(err) {
  console.log(err); // 'not authorized' not output, 
                    // since this is a '/customnamespace' event handler
});

The client needs to handle both the events coming from the global namespace and the custom namespace, otherwise the socket connection seemingly hangs on the client side as it receives no feedback from the custom namespace event handlers. None of the socket.io documentation seems to cover this shortcoming.

You can simply get any namespace socket from the socket Manager by calling Manager.socket([namespace]). To get the socket Manager from any socket, simply reference the ‘io’ property of the socket object. From there we would use ‘/’ to get the global namespace socket.

Here’s the proposed workaround that continues the sample client code above:

var socket = require('socket.io-client')('http://localhost/customnamespace');
var manager = socket.io;
var socketGlobalNs = manager.socket('/');

socket.on('error', function(err) {
  console.log(err); // 'not authorized' not output, 
});

socketGlobalNs.on('error', function(err) {
  console.log(err); // This will output 'not authorized'
});