namespace authentication messages are missed
Hi, I've been trying to get socketio-auth working with a site that uses namespaces. I could be missing something but I think I've found an issue and written a fix that works for me on my fork. What do you think? Thanks, Scott
Problem:
- socketio-auth only listens for incoming connection events on the io object itself, not on each namespace.
- When an incoming socket connection to a namespace opens on the server, it seems to add a socket to the root namespace and the namespace it connected to (they have the same socket ids, however).
- The authentication message from the client comes in on the namespace socket and not the root namespace one. The message is missed because socketio-auth is listening on the root socket.
- The timeout then fires and disconnects the root socket which disconnects the client socket.
Proof of concept fix on my fork:
- Add connection listeners to all namespaces, each with their own timeout.
- If a socket is authenticated, search each namespace for sockets with the same id and for each of these sockets:
- restore the connected socket.
- emit an authenticated message.
- call postAuthenticate.
Hi @scottdupoy, sorry for the delayed answer, thanks for bringing this up. I think the current code is meant to block and restore connections on every namespace (including the default one), but there could be a bug. Can you show an example of the failing scenario and a link to the code of the fix you've mentioned?
Closing now, you can reopen when you have the sample failing code.
Hi @facundoolano! I faced the same issue - authentication didn't work when using namespaces. I have just tried @scottdupoy 's fork, and it worked! Please see his last commit, which fixes that issue: https://github.com/scottdupoy/socketio-auth/commit/01fda32dda3af5a91a53578eb91e740d575d0e3b
Facing probably the same issue.
Would be great to merge @scottdupoy 's commit if it fixes the issue.
That commit seems like a major rewrite and would probably require updating the tests. I'm reopening this, but unfortunately I have other priorities right now. If someone sends a PR with tests passing and a new test for this scenario I can review it and merge, otherwise it'll have to wait.
+1
I ran into this problem today as well. Is there a suggested workaround besides not using namespaces?
@scottdupoy @joshrickert or anyone else who stumbles on this older thread may want to know how I got this working. I did see this project is no longer maintained FWIW. You just need to pass in the namespace object instead of the io object. This would mean you have to do this for all namespaces.
var io = require('socket.io').listen(app);
const myNamespace = io.of('/myNamespace');
require('socketio-auth')(myNamespace, {
authenticate: function (socket, data, callback) {
//get credentials sent by the client
var username = data.username;
var password = data.password;
db.findUser('User', {username:username}, function(err, user) {
//inform the callback of auth success/failure
if (err || !user) return callback(new Error("User not found"));
return callback(null, user.password == password);
});
}
});
I ended up rolling my own auth middleware, wasn't too painful.