Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket.io namespaces and server don't share middleware?

I'm created some passport authentication middleware for my socket.io/express app. It looks like:

io.use(function (socket, next) {
    var data = cookie.parse(socket.handshake.headers.cookie);
    var sessionID = cookieParser.signedCookie(data['connect.sid'], 'my balonga has a first name');
    sessionStore.get(sessionID, function (err, data) {
        if (err) next(err);
        socket.handshake.passport = data.passport;
        next();
    });
});

It works great, but I have a namespace and it appears uses a different socket. Does this mean that I must reuse my middleware for each namespace?

I noticed that I connect to my namespace it calls the middleware for the base server and then the namespace, this means if I include the middleware in both places, I'm doing 2x the operations I need. Can I prevent this without removing the middleware at the base layer? None of these are app breakers, but it will change my architecture a bit and I'm concerned I'll have auth gaps at some point.

Summary:

  • Must I reuse my middleware for each namespace?
  • Can I prevent the default namespace middleware from being called without removing the middleware at the base layer, when it is a namespace being connected to?
like image 601
Chris Anderson-AWS Avatar asked Jan 11 '15 06:01

Chris Anderson-AWS


1 Answers

Must I reuse my middleware for each namespace?

No. If you plan on using the middleware, as written, for all namespaces, you can utilize io.use() like you are currently doing. This places the middleware on the default / namespace. As you have already noted, the middleware on all sub-namespaces fire off in order, starting with the default, on a new socket.io connection.

Can I prevent the default namespace middleware from being called without removing the middleware at the base layer, when it is a namespace being connected to?

No. All namespaces are a subspace of the default namespace and any middleware defined on the default namespace, will fire for all connections. If you wanted to only fire your middleware off on certain namespaces, you could refrain from using io.use() and do the following.

const myMiddleware = function(socket, next) {
    // Do stuff here
};
io.of('/nsp_1').use(myMiddleware);
io.of('/nsp_2').use(myMiddleware);

A More Modular Approach

A more modular way to do this is to put the handlers for different namespaces in different different files, and define middleware specific for those namespaces in those files, while using io.use() for the default namespace.

main_app.js

const everthingMiddleware = require('./middleware/everything.js');
io.use(everythingMiddleware);
require('./nsp_1.js')(io.of('/nsp_1'));

nsp_1.js

module.exports = function(io) {
    const onePlaceMiddleware = require('./middleware/oneplace.js');
    io.use(onePlaceMiddleware);
};
like image 197
nickanna_42 Avatar answered Oct 12 '22 01:10

nickanna_42