-
Notifications
You must be signed in to change notification settings - Fork 10.1k
Common authentication for all namespaces in socket.io 3 #3842
-
Hi,
I'm confused about how authentication is intended to work when you have multiple namespaces in socket.io 3. We currently (with socket.io 2) use something like https://github.com/socketio/socket.io/blob/master/examples/passport-example/index.js, where we put authentication middleware on the '/' namespace. This then gets executed for every connection.
But we cannot do this with socket.io 3, since sockets no longer always connect to '/'. Instead we have to add this middleware to all namespaces, which seems a bit risky. What if someone uses io.of('foo') in some part of the code, but forgets to add authentication middleware to the namespace? Everything will seem to work, except that the namespace is accessible to all.
Am I missing something, or is this the best option?
(I also tried the 'allowRequest' option when creating the server, but that seems to cause the client to keep trying to connect after being rejected. We also have some other things we do on every new connection, which makes this a less attractive option.)
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 3
Thanks for raising this issue, that's indeed a change from v2 to v3.
A possible workaround would be to override the io.of
method:
const of = io.of; io.of = (...args) => { const nsp = of.call(io, ...args); nsp.use(yourMiddleware); return nsp; }
Dynamic namespaces could work too, depending on your use case:
const parentNamespace = io.of(/^\/dynamic-\d+$/); parentNamespace.use(yourMiddleware); // attached to all child namespaces
Replies: 2 comments 6 replies
-
Thanks for raising this issue, that's indeed a change from v2 to v3.
A possible workaround would be to override the io.of
method:
const of = io.of; io.of = (...args) => { const nsp = of.call(io, ...args); nsp.use(yourMiddleware); return nsp; }
Dynamic namespaces could work too, depending on your use case:
const parentNamespace = io.of(/^\/dynamic-\d+$/); parentNamespace.use(yourMiddleware); // attached to all child namespaces
Beta Was this translation helpful? Give feedback.
All reactions
-
Okay, thanks! Good to know I wasn't missing some big obvious thing.
Overriding io.of
would work, with the tradeoff that it makes the code more confusing. I'm leaning towards just being disciplined when creating namespaces, but we'll see what we decide on. Good to know the option exists, anyway. (Dynamic namespaces wouldn't work for our use case, since the server emits to explicitly defined namespaces.)
It would be a useful feature to be able to define global middleware, I think. All three examples in the docs (auth, logging, rate limiting) seem like things you would often want to share between namespaces.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
That sounds reasonable 👍 : #3851
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
Even though this sort of works the behaviour is entirely different.
Before if you had an auth middleware on the default namespace you would only authenticate once. With this solution the authentication process will occur for every namespace.
I fixed this by adding a promise to the socket.client to be reused, however that feels like a hack.
@darrachequesne It would be beneficial to have a one call to handle authentication process as you could before.
Beta Was this translation helpful? Give feedback.
All reactions
-
any update on this? I also would like to add a middleware for all namespaces.
Beta Was this translation helpful? Give feedback.
All reactions
-
I guess we could indeed add it. Any suggestion for the method name?
Beta Was this translation helpful? Give feedback.
All reactions
-
useDeep?
Beta Was this translation helpful? Give feedback.
All reactions
-
useGlobal?
Beta Was this translation helpful? Give feedback.