How to configure Autobahn(crossbar.io) for dynamic chat rooms? - javascript

I love crossbar.io and how it works(personally). But I would like to know how we could setup the architecture for a typical dynamic chat application using Autobahn(Crossbar.io).
Dynamic chat here means, individual chat room created for each url.
For example: http://www.myapplication.com/chat?roomId=123 , creates a chat room subscribing to topic "com.myapp.chat123".
http://www.myapplication.com/chat?roomId=456 , creates a chat room subscribing to topic "com.myapp.chat456".
We need to store the chat messages in the Database for future reference, since Autobahn doesn't have message persistence.
Now my questions are:
If each chat room use separate topic, then how we could subscribe for the messages in the server(since we can't subscribe using Patterns as of now) ?
Since we will use separate topic for each room, how we do authentication and authorization in Crossbar.io ?
I couldn't able to find the Javascript documentation for setting the features as mentioned here. Where to find it ?
In this SO answer, it was mentioned that crossbar.io provides meta-events for session join or leave on Router. Is there any way to know when user subscribes or unsubscribes to specific topic instead of Router join or leave ?
Could you explain how to configure available advanced profile features with Current version of Crossbar.io (in Javascript, browser or Node.js) ?
Could you explain about Event History feature in detail ? And how to configure it ?

I'll answer your question one by one:
At least, it's your client which wants to subscribe to his topic (correct me if I misunderstand), then, you need to store a list of topic ID related to user in your database, and when your client connects to the server, you send him the list of topic ID and let him subscribe all of them.
Authentication / Authorization process has nothing to do with a separate topic. You can do something like that:
There is two way to authenticate, anonymously and WAMP-CRA. Then, you assign a role for anonymously connected clients, and another role for authenticated client (this role can be different following the database e.g: user, admin, moderator, ...)
When authenticated, subscribing to a topic needs authorization (implemented by a dynamic authorizer, you can see how to do it there: https://github.com/tavendo/AutobahnPython/blob/master/examples/twisted/wamp/authorization/router.py -- basically, it is the same, except you forget the router thing and you focus on the authorize method)
Then, you authorize based on something like Access Control.
Unfortunately, the doc is quite outdated, you should ask for it on the Mailing List which features you want to use and how can you use them.
As I recall, there is a meta-event on_subscribe/on_unsubscribe.
Advanced features can be configured in the config file of Crossbar, they can be also an argument passed to publish/subscribe/call/register calls.
I'm not a core developer of Autobahn, but as much as I understood, it is a feature that give you a way to get all previous published data from a topic (X last ones, since a TIMESTAMP, after a ID).
I know that Autobahn is hard to follow sometimes due to the documentation, but examples can help a lot, and here there are a lot of interesting things: https://github.com/crossbario/crossbarexamples (including Authentication, MetaAPI, Patterns).
I hope that I've answered most of your questions, but yet, if there are things you don't understand, I recommend you to go to the mailing list, this is your best try, in my opinion.

Related

Web Push Same Subscriber Different Endpoint Issue

I am trying to implement the web-push service in one of my projects. So, I actually need to know the actual subscriber numbers in my app. So what problem I am facing is, the service worker generates new endpoints for the same user and I didn't find any unique thing by which I can figure out if the subscriber exists or not.
All my users are also guest users so I don't have any unique thing. There is also an event called onPushSubscriptionChange which doesn't also work in other browsers except for Mozilla.
So is there any way to uniquely identify a user? Like if multiple endpoints are created for the same user then I want to replace the old endpoint with the new one in my database. I am not willing to use cookies also.
Another thing is does firebase cloud messaging solves this issue?
Thank you

Disable Meteor Router.routes on browser console for unauthenticated user

I am working on a Meteor application that uses Iron Router. We have a login page in our application. Even when the user is not logged in, if I call the below code on developer console as un-authenticated user:
Router.routes
It gives all the routes and the respective paths. Is there a way to disable access to these paths or do I need to push these end points in the server code ?
Everything you define on the client is visible on the client. So is all the routes definitions and routes logic, too. In production code this will be obfuscated but it's still there.
If you are concerned, that clients can read your routes, then you should be more concerned about the fact that it concerns you. Sounds a bit confusing but the point is: you should double check each data published to client via publications or manipulated / created via methods on server. If your backend is robust and secured as much as possible (100% will never be possible), then you don't need to care, if clients can see which routes exist and get access to them.
An example:
Bob found the route /admin and disabled the router's triggers to redirect him if he is not Admin.
Now Bob could see all data, that Admins can see. To prevent this, you may check in the publication if Bob has the role 'admin' on don't publish to him if he's not admin.
Ada also found this way to the Admin panel and wants to create a new user. Because your server method for creating new users is a ValidatedMedthod that checks if Ava has the 'admin' role it will fail to create a new user, because Ava is not an admin.
Conclusion:
Preventing access on the client side is just UI Magic bot not secure at all. Simple tweaks, however on the server side will help you to sleep better.
More help:
A good way to get started is to read the Meteor Security Guide:
https://guide.meteor.com/security.html
There is also at the end a security checklist, which I just cite for completeness and SEO reasons here:
Make sure your app doesn’t have the insecure or autopublish packages.
Validate all Method and publication arguments, and include the audit-argument-checks to check this automatically.
Deny writes to the profile field on user documents.
Use Methods instead of client-side insert/update/remove and allow/deny.
Use specific selectors and filter fields in publications.
Don’t use raw HTML inclusion in Blaze unless you really know what you are doing.
Make sure secret API keys and passwords aren’t in your source code.
Secure the data, not the UI - redirecting away from a client-side route does nothing for security, it’s just a nice UX feature.
Don’t ever trust user IDs passed from the client. Use this.userId inside Methods and publications.
Set up browser policy, but know that not all browsers support it so it just provides an extra layer of security to users with modern
browsers.
Useful packages mentioned in the answer:
mdg:validated-method
alanning:roles
audit-argument-checks

How do I handle communication between multiple Node.js servers for each user?

I'm trying to make a user log in just once, and have his information on all the servers. Any changes made to the user's information will instantly be available for all servers. Is this possible to do without having each user "log in" separately for each server?
Sort of like the $_SESSION for php, but for Node.js
Design 1 -
What I think would be best to do, but don't know how to share socket data between servers, perhaps using something like PHP's $_SESSION?
Design 2 -
What I'm currently doing:
User uses socket.emit to main.js
main.js adds user information onto the emit
main.js emits to the appropriate server
Appropriate server emits back to main.js
main.js finally emits back to user
This seems awfully inefficient and feels wrong
If your information is primarily static, you can try something similar to JWT. These are cryptographically signed tokens that your authenticating server can provide and the user can carry around. This token may contain information about the user that you want each server to have available without having the user accessing it.
If it's not, you may be looking into sharing a database across all servers, and have that be the point of synchronization between them.
Updates based on our comments (so they can be removed later):
If you decide to use auto-contained JWT tokens, you don't need to be making trips to the database at all. These tokens will contain all the information required, but it will be transparent to the end user that won't have insight into their contents.
Also, once you understand the JWT standard, you don't necessarily have to work with JSON objects, since it is just the serialization approach that you can switch by another one.
You'd provide one of these tokens to your user on authentication (or whenever required), and then you'd require that user to provide that token to the other servers when requesting information or behavior from them. The token will become your synchronization approach.

Socket.io client-to-client logic, with lot of users

I am trying to implement client to client messaging in my app, using socket.io, and node.js and Android.
I searched a little, and found a lot of tutorials, explaining how to deal with targetting specific client when sending messages through socket.io socket.
Send message to specific client with socket.io and node.js
The solution is almost always the same : Creating a hashmap object, linking user info such as its username, email address (or anything unique allowing to identify it), with its socketid.
Then calling io.clients[sessionID].send()
Now I have two questions :
This would work if only one instance of the app is running, but imagine if my app is divided in multiple instances (for large app).
What if a client A, connected to instance X, wants to send message to user B, connected to instance Z. If, as seen in the example, socketids are stored directly in a simple object existing in the script, some sockets wont know about others users existing in an other instance.
If I am totally wrong (and I might), is this a good practice to store all user's socketids in a single variable ? If yes, would it still be okay with a 50000+ users enviromnment ? If no, should I find another solution like storing user's socketids in database ?
You could use a redis instance, shared between all your app instances. And you get 2 birds with one stone.
The redis would store all your socket ids in a centralized place.

SignalR - invoking a message from server code

Been researching heaps and making no progress :(
Trying to set up a small web app using VB in VS 2013.
I have added all the SignalR resources to my project.
Each logged in client has a UserID in my database.
I want to invoke a SignalR message to certain UserID's from server-side code, not client-side. Firstly, is this possible? (it was possible using ReverseAJAX, but I have chosen not to use that)
If it is possible, how do I go about setting up the SignalR Hub to allow me to send a message using a UserID? I don't need help with the SQL, I can do that my self.
Also, what javascript do I need to persist the request? I'm guessing I will need the UserID somewhere in this piece of code.
Thanks heaps.
This is very possible. If you look here
http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#callfromoutsidehub
you will find a section on "Single User Groups". This is the mechanism available in version 2 to send a message to a single User Id. Essentially when a Connection is established you add the User Id to a "group" which can be accessed by Group Name (syn. User Id) without having to worry about persisting the relationship of a connection id to a user id yourself. The only limitation would be if more than 1 connection is established by the same user, all devices with that user would be in the same group and would therefore receive any messages sent to it...
There is also another section on how to retain the instance of your SignalR context on the web server to make calls out to clients (How to call client methods and manage groups from outside the Hub class)
I did read something about the SignalR team creating User Id methods but I have used the above approach with fair success and haven't looked much further into that.
Hope this helps
As #Pepto mentioned, here it is described how you can get a reference to your hub, and then use it in your server code.
An easy way to invoke a client-side function for a specific user, would be to use Clients.User("Username") in your hub.
Intellisense will tell you that User() wants an ID as a parameter, but you should pass the username of the user, whose function you want to invoke, not his ID.

Categories