I understand routing (I think), but what's to stop User A from looking at User B's client-side source to discover the socket.io URL specific to each user and then build their own script to start listening for broadcast messages on that particular channel?
You would need to use something to determine who the client is. Once you do that, you could for example use the rooms feature, and only broadcast to the specific room where you put all your authorized users.
To identify the client, you could pass in cookies from the browser in a socket.io request, and compare that to any session data you have stored in Express/Connect/Whatever.
Related
I am currently working on a web application using the MEAN stack. It has a social aspect to it so I want to be able to push notifications to users.
The way I do it now is when something happens that should be a notification it gets stored in a mongo database with an unread flag. Each client will send a get request to the server every 30 second and will receive every notification marked as unread, and will then mark it as read.
I want to switch to using a message queue and sockets so less network resources will be used, and also provide the user with a real-time experience. I've thought about using redis and its pubsub structure but I can't seem to figure out how to do this securely. If I push out notifications to the affected users, won't it be easy for someone malicious to subscribe to somebody else's channel and receive notifications not meant for them? Am I missing something or is it just the wrong approach for such a system?
Edit: Figure I update with the solution I went with if anyone else reading this is having the same problem.
Instead of using rabbitmq, as the answer suggested, I figured that a much more easy and elegant solution is to just use socket.io. When new sockets connects to the server I save a mapping from the userID to the socketId in a redis in-memory DB. (After I've validated their token) That way, if I need to push a notification to a user I just look up the socketId in the redis DB, and then send it to the correct socket.
This way I don't need any security beyond that as socketIDs are unguessable, and the message is only sent across the single socket that belongs to the given user.
This way it will only get sent through the connection of the given socket, as socketIDs are only used server side to keep track of all the connection. This means no one else can "listen" using someone else's socketID.
you can use RabbitMQ for this. Also authentication is there. Please go through following link and try.
https://www.rabbitmq.com/access-control.html
also, you can apply authentication in existing structure using subscription auth tokens with all subscribed users only.
even redis has its security with topics. Please have a look in link below
https://redis.io/topics/security
I'm building an application in real time with socket.io
Each time the user enters the application creates a socket ID.
So if I joining the application in several browser tabs generates me a socket id for each tab.
I generate a room for specific users and included my sockets id,
but I need to emit broadcast message except to my sockets id.
This code don't work for me because emit broadcast message but sends to my other id sockets
socket.broadcast.to("room").emit('message', "somethings")
Any ideas?
Assuming you are using some application framework like express along side socket.io, you can use the valid session id obtained from Express.js for maping the socketIDs generated from the same session.
Other than maping the socketIDs to the sessionID, I dont think there is a way to obtain all the socketIDs generated across tabs as the information on other tabs wont be accessible in the current tab context.
Below are few existing questions discussing this same case:
manage-multiple-tabs-but-same-user-in-socket-io
socket-io-and-session
I am trying to integrate real time notifications with Node and socket.io in a Symfony Application. I have read a lot of information about this topic and have a working Node application.
nodeClient.js
var socket = io.connect( 'http://192.168.15.106:8080' );
$('a.sendSmile').click(function(){
socket.emit( 'message', { name: 'something' } );
});
socket.on('message', function(data){
console.log(data.name);
});
The problem now is with the above which is working perfectly I am able to send real time notification to all the users at once. But what's the best way to target a single user?
For example a user can send a smile to another user so only the second user should receive the notification and not all the users.
Should I make multiple listeners for node? or any other method to do this?
You need some way of identifying which socket that connected to your server is the one you want to send data to and then you can send to just that socket. You can keep track of user names when users connect or if you have some auth system, you can keep track of which socket belongs to which authenticated user.
Your server holds a list of connected sockets. Each connected one at a time and triggered a connection event on your server when they connected. Your application needs to create a way of knowing which of those connected sockets you want to send the data to. This is not something you've described anything about how you want that to work so we can't really help more specifically.
You can dispatch a notification to single user if you can discriminate that user. For example you can get a user_id on client connection to your nodejs server (the user_id is send from client, inside message) and save it in a key-value store (like Redis, memcache, ...). In this way you can correctly dispatch the notification, arrived from the server (like Symfony2 application), to right user.
I suggest you use Redis, both as a key-value store and for its implementation pattern of the publish/subscribe usable as a channel of communication between the server and the application of realtime.
In our app, every time a user signs in a new connection in socket.io is created. So if a user signs in simultaneously on more devices, they behave as separate connections. Instead of creating a new connection every time, I'd like to check whether the user is already connected to socket.io and if he is, I'd like to connect him to already established connection. How can this be done?
From the socket.io perspective, those ARE two connections. But if it was my app, I would do something like this:
add a user identifier (userid, username, something you identify users by) to both the users' socket.io connection (so, each time you send a message to the client, you also pass this id)
pass this id also to the client-side code on init.
So now the socket on the server side has its' socket.io id, but also your user id. Anyway, to proceed:
send this user-id to the client in it's javascript files.
on the client-side code, make a small adjustment to socket.io handler - for each received message (say, broadcast), you can now check if it's your current user-id and instead of saying 'User #351 says Hi' you can say 'You said Hi on another device' or something like that.
Of course, I'm not socket.io expert, there's could already exist a framework or lib addressing this.
I started looking into node and socket.io.
I already have created a simple chat application and I am amazed at how easy it was.
Now, I would like to take a little bit further and provide a list of online users that have the ability to chat with each other in private.
What would be the best way to approach this?
I read on 0.7's new room feature. Would that be a way to go? Dynamically create a new room each time 2 users need to chat in private? But how the second user is going to be notified of the new room created, so that he can connect there?
Is it better to handle all the above logic myself? Store the rooms and users server side and loop through them each time and send messages to the appropriate ones?
Thanks
If the only functionality you want is for two people to be able to send messages to one another (and not groups of people to have a room), then the logic could be something like this:
When a user connects, store their connection in an object keyed by their username (or in any other data structure that ensures you can find a specific user's connection).
When a Bob wants to talk to Jeff, send the server an event stating such.
The server looks up Jeff's Socket.IO connection in the object from step 1.
The server uses this connection to send Jeff (and only Jeff) the private message.
Hej Thomas
if theres only 2 users talking you dont need use publish att all just send that message from the client to the server and let the server locate the other client and send it down.