NodeJS connect two user among many of loggedin? - javascript

i'm experimenting node.js and made a cool chat application followed by this article using socet.io!
Then i have added a authentication system using Passport.Js into my test site.
How i would do this: among many users, user X want to send some kinds of notification to user Y not to other users!!
I am using the emit() function with a custom event called notifybuzz
but when a user send a notification it goes to all accounts!!

This article mentions that you will need to use the form socket.broadcast.emit('hi'); to send to limited recipients. the challenge will be to keep track of your socket connections, and relate user information to them. Once that's done, you'll know exactly which socket to send your message over.
Best of luck!

Related

How can I prevent bots and spam API requests?

I'm working on an Android app in react-native and the app communicates with an API I'm working on for the app. The API is built with Laravel and Laravel Passport.
I know that Android apps can be decompiled so any secret keys stored within the app could be easily found. This is the reason for my current approach.
You can only gain an access code during registration. The application uses anonymous accounts so if you lose the access token, it's too bad. The app makes an API request to /api/register which creates the account and returns an access token. The app would store the token and use it to make further API requests.
The problem is that the registration route does not use any client secrets or access tokens. It is very easy to automate requests to the route and create an army of bots. I could potentially limit the amount of requests like a lot of API providers do but that wouldn't stop the issue.
I've heard about payload hashing but this usually requires a salt that is in both the app and api. Again, this is not secure and couldn't someone just hash it themselves if they know the salt to spam requests? Maybe I'm misunderstanding how payload hashes work.
Hopefully someone can assist.
You'll probably want to use something to detect the user agent hitting the route. This package has a lot of useful features:jenssegers/agent. For example, it offers crawler detection:
$agent->isRobot();
Depending on your hosting provider, you may have access to tools that automatically blacklists ip addresses after X number of requests per minute (or other metrics). I know AWS offers this service.
Another option is antonioribeiro/firewall. Track users based on ip or geography and redirect/block accordingly.
I'm at this junction at the moment and the route I'm taking is one where the user is challenged to solve a simple puzzle:
registration process on app/web picks up a challenge from my registration server
the challenge is shown to the user with the input fields: email/username, password and the answer input for the challenge
it all gets sent to the registration server and if the answer is incorrect, the registration is denied
This "are you human" challenge is what will stop bot-registration so it needs to be a little smarter than the one coding the bots, so a selection of various challenges on the server would be nice.
I'm thinking of "select the n-th value from the dropdown", "select the first/last option", "write the color 'blue'" or "what whole number is between 3 and 5", and so on, for which variables can easily be generated by the server, the challenge and answer input can easily be created by the registration script, and it's easy and not very time consuming for the user to solve.
Another option I'll explore is to throttle requests by IP, combined with black-and white-listing those.

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.

Allow same user multiple login on different number of devices and how to deal with sessions?

I'm building a chat application with some php, mysql, nodejs, socketio.
I want to allow users to be logged in from nomatterwhat number devices. Like eg. Facebook where it doesn't matter which screen you're looking at. They all reflect the latest changes.
Tested it right now and it works that way. If i open the notifidations the number dissappears on the same page on different devices.
My guess -and started building with that iedea in mind – was that a room is created for each user when a user logs in the first time and any following login from the same user is also added to that room so the changes can easily be broadcasted to the room.
All browsers are aware off the multiple logins because i send a soclet-message to the room setting a variable - multilogin- so that it knows that there are more.
Also needed to see when a user clicks on the logout-buttons it send that information along.
If it is the only one logged in it should kill the session set the user offline.
Actions performed on one device, broadcasts it to the other members in the room etc.
Seems logical?
It works so far but i'm uncertain about the session part of this setup.
The logic in php -inherited from the origanal build of the chat – checks the user logging in to see if the user is already logged in and if so, it destroys the existing session first and then sends a loggout command -which i prevent now when the multilogin parameter is send along- to the other browser.
My question now is, what could be a logical approach towards the sessions?
I was playing with some ideas in my head and then i thought, let's look on the internet about the subject.
An idea could be that only the first loggin in gets the session created and is shared by sending the id to the others so they can be identified as being the same user.
Would that be an approach that one would suggest?
Found a simple solution by letting each device with same user that logs in getting a new sessionid which is send to the others (socket message to room) so their sessionid becomes the same to authenticate themselves to the server. Session id is save enough for that purpose.

Using Amazon Simple Notification Service (SNS) in the client-side

is possible to use the AWS SNS in the client, with Javascript?? I am creating a website that has a booking form , and I would like to send an email notification as soon as the user presses the submit button, for this I thought of using the Simple Notification Service, however I 'm not finding the documentation using with the client side. Would anyone tell me if it is possible ? I've searched on google and did not get a satisfactory answer.
Yes, you can use SNS from the client, the SNS JavaScript SDK explains how you can do that.
However, as John R said that's the wrong tool for the job. You really want to be using SES to send email.
Regardless of which one you use the biggest obstacle is not the code, it is the authentication from the client side, look here to get started.
For whatever its worth, I do not think that's your best approach. Unless your users can spot milli second differences I would just do it on the server side. I do not know what server side language you are using, but any of the ones that have an AWS SDK make this trivially easy to do.
Note though that AWS does not allow you to send production emails before you are verified. I would suggest you read through the AWS documentation for SES first. They are pretty comprehensive.
The Amazon Simple Notification Service can send a notification to subscribers in several ways:
Email (but with an 'unsubscribe' footer)
SMS
Mobile push
Push to an Amazon Simple Queue Service (SQS) queue
Messages are sent to an SNS Topic. Any subscribers to the topic then receive a copy of the notification. All subscriptions to a Topic must be confirmed.
Therefore, I would not recommend using SNS as a method of sending an email to your users. Instead, use the Amazon Simple Email Service (SES), which is designed to improve deliverability for outbound email.
There is a JavaScript SDK that can connect to SES.

Categories