How to implement a like feature on a MEAN web app efficiently? - node.js

I am building a web app wherein a user can like some choices displayed on the page.
I want to build this like/unlike system in the most efficient way possible. Does every press of the like button need to send an http request to the node.js server to modify user data in Mongo?
I'm asking since I will be having a python script as a recommender system that listens to every change happening in MongoDB.

Yes, every click should go to the server by making a callback. Someone can say that:
you can also do tweaks with this functionality like pop all the ids of posts liked by a specific user in an array and send it back at the end of its session or after a specific amount of time.
But think what if that array somehow lose the data by mistake ? Or the session is failed due to some reasons? Also, how will other users see that which post is liked or not ?
See these are the reasons we always send the response back each time. However JQuery and other frameworks are there to make it fast.

Does every press of the like button need to send an http request to the node.js server to modify user data in Mongo?
You need to get your data to the server somehow, yes. An HTTP request is generally a good choice, and doesn't have to be as heavyweight as it once was.
Firstly, your server should be enabling HTTP keep-alive, where the underlying TCP connection stays open for some amount of time once the request is finished. That way, subsequent requests can be made on the same connection.
Additionally, you should ensure you have HTTP/2 enabled, which is a more efficient protocol due to its binary nature. More importantly, headers like Cookie and what not aren't sent over and over again.
By following these best practices, you'll find that your request/responses are just a few bytes down the wire of an existing connection. And, you won't have to change anything in your code to do it!

Related

hide fetched user data from backend

I am looking for how to to get user data and expose it in the UI without show it elsewhere in devtools - so I would like that data doesn't appear in any request response.
I considered different possibilities, as cookies or session but none of them allow to hide the data before it is displayed in the UI.
So I wonder what the usual practice is and if using socket.io would be considered a hack?
The idea is:
User is logged and visits some page, regular API requests are made and serve UI display, and is required user data for UI purposes.
As an example:
Are displayed elements to which it is possible to subscribe, so depending of user and of its subscriptions, style is different between followed and unfollowed elements.
Thank you in advance for your help.
I don't get the "why" you would want to do that. The normal user doesn't open devtools. The "hacker" user will most certainly not be prevented from getting that data. In the end there're more tools than just the browser's devtools to sniff incoming and outgoing data and since that is something you cannot prevent, there's no reason to do it in the browser in the first place.
What you can do though is encrypting the response in your backend and then decrypt in your frontend. Since you need to send the decryption password as well this will still not prevent anyone from decrypting the response messages, but obfuscating the decryption part somewhere in your code can at least make it a little more difficult (emphasize "little").

configure express req.session with cookie disabled

I have a node.js webserver with express middleware. I am trying to eliminate the need to session stores for performance reasons. I dont track much as of now.
However, I do need to keep track of username and userid when a session is started after loggig in. I have implemented this using express res.cookie( ... ) which works if cookies are enabled. But it will not work if cookies are disabled.
so I was looking at req.session but that again uses cookieSession internally.
Q1: How can I keep track of username (once user has loggedin )
across multiple requests with cookies disabled in browser and NO-SESSION-STORE
(REDIS/MONGO etc)
Q2: In the solution for Q1 above, I want webserver to be stateless,
so it does not grow in memory at any point?
Is it possible? Does my question/requirement even make sense? I am new to this.
Essentially I am looking for an object other than cookie that can be part of request which will communicated every time request is sent/received
Please help
There are multiple avenues you could potentially take, since it sounds like you control the requester as well as the backend service.
HTTP Headers
Query String
Cookies
We know cookies are out.
With HTTP Headers, you can't always count on them unless you're making some kind of AJAX call.
Query strings require you to ALWAYS send back a user name or other identifier manually. However, it would solve Q1 and Q2.
Depending on what your app is, it might make sense to re-architect endpoints so that they are ReSTful and help define actions - that way it makes semantic sense to have a username as part of the request url.
For example:
GET http://example.com/:username => could display a profile
GET http://example.com/:username/friends => could display a list of friends.
Depending on how your app is designed, you might also be able to utilize websockets to handle user connections and auth.

Sencha-Touch : Secure a user submitted form

I am using Sencha Touch for some weeks now, and I plan to add to my webapp, a form with which users can contribute with informations. I was wondering of means of securing this form, since it will directly post entered data through an Ajax call to my server. It will not be too difficult for someone to sniff http traffic and write some script that would kill my database server sending data to my submit server side action.
I was wondering about using recaptcha, but I cannot see how to implement it or neither if someone has tried it. I am open for any other form of security that could be easily implemented in the context of sencha touch
Thx
Create some simple form of captcha if you want. Like addition of two numbers etc.
You wont prevent sniffing http traffic using a captcha, use ssl, if you send your requests using https no one can sniff your trafic.
But even that cannot prevent someone sending a crafted request to your sever trying to exploit it, since they can tell by looking at your client code what is the server expecting.
You can try to obfuscate your client code, but that wont help much either.
The only way to prevent it is by validating the requests on the server side and invalidate all the requests that can potentially harm your system.

How to detect browser close at server side in asp.net?

I wanted to know when the browser is closed at server side in asp.net 2.0. How to detect in code behind?
Short answer: you can't do that directly since http is stateless. Perhaps you can use some AJAX hearbeat pooling, session timeout detection and other tricks.
Take a look at this question for more explanation and ideas. This is Java based, but ideas are language agnostic.
client side script:
< body onbeforeunload="window.open('http://www.website.com/browserclosed.aspx','mywindow','width=1,height=1');">
server side script (browserclosed.aspx):
// page_load
int userId = Convert.ToInt32(request.session("userId"));
ReportBrowserClosed(userId);
// Do what you want in ReportBrowserclosed() method
The first thing that comes to mind is that you hook the unload event and just asynchronously post back that the browser navigated away from your site (closed the window). However, the way that HTTP is being used to build stateless web sites makes this infeasible. You just don't have a reliable way of tracking user connectivity.
Just consider how would you handle multiple sessions? If I have the same site open in many and several, tabs or windows and close down all but one how do you tell that I'm still connected? And for the fun of it, say that my browser crashed somewhere there in between.
The thing is, I could design something that would sort of solve your problem. However, it's never going to be reliable because HTTP doesn't have a built-in control mechanism for connectivity.
I have to answer this question, with a follow up question. Why do you need to know when the browser window closes?
If you need to do some resource clean up there's two server side events, facilitated by ASP.NET that you could use more reliably. And that's Session_End or Application_End.
The quite obvious question is why do you need this? Do you want to store logout time or closing time? Then its better to catch in session timeout. Do you want to redirect some other page then its better to catch in page unload event of javascript.

cheat prevention for browser based xmlhttp/js/perl/php game

Lets say that in a browser based game, completing some action (for simplicity lets say someone clicks on a link that increases their score by 100) clicking on this link which would have a url for example increase_score.pl?amount=100 what kind of prevention is there from someone simply sending requests to the web server to execute this command:
Over and over again without actually doing the task of clicking on the link and
Sending a false request to the server where amount is set to something rediculus like 100000.
I am aware of checking HTTP_REFERER however I know people can get around that (not sure how exactly) and other than some bounds checking for the 2nd option I'm kind of stumped. Anyone ever experience similar problems? Solutions?
Nothing can stop them from doing this if you implement your game how you propose.
You need to implement game logic on the server and assign points only once the server validates the action.
For example: on SO when someone votes your question up, this isn't sent as a command to increase your reputation. The web-app just says to the server user X voted question Y up. The server then validates the data and assigns the points if everything checks out. (Not to say SO is a game, but the logic required is similar.)
Short version: you can't. Every piece of data you get from the client (browser) can be manually spoofed by somebody who knows what they're doing.
You need to fundamentally re-think how the application is structured. You need to code the server side of the app in such a way that it treats every piece of data coming from the client as a pack of filthy filthy lies until it can prove to itself that the data is, in fact, plausible. You need to avoid giving the server a mindset of "If the client tells me to do this, clearly it was allowed to tell me to do this."
WRONG WAY:
Client: Player Steve says to give Player Steve one gazillion points.
Server: Okay!
RIGHT WAY:
Client: Player Steve says to give Player Steve one gazillion points.
Server: Well, let me first check to see if Player Steve is, at this moment in time, allowed to give himself one gazillion points ... ah. He isn't. Please display this "Go Fsck Yourself, Cheater" message to Player Steve.
As for telling who's logged-in, that's a simple matter of handing the client a cookie with a damn-near-impossible-to-guess value that you keep track of on the server -- but I'll assume you know how to deal with session management. :-) (And if you don't, Google awaits.)
The logic of the game (application) should be based on the rule to not trust anything that comes from the user.
HTTP_REFERER can be spoofed with any web client.
Token with cookie/session.
You could make the link dynamic and have a hash that changed at the end of it. Verify that the hash is correct given that period of time.
This would vary in complexity depending on how often you allowed clicks.
A few things to note here.
First, your server requests for something like this should be POST, not GET. Only GET requests should be idempotent, and not doing so is actually a violation of the HTTP specification.
Secondly, what you're looking at here is the classic Client Trust Problem. You have to trust the client to send scores or other game-interval information to the server, but you don't want the client to send illegitimate data. Preventing disallowed actions is easy - but preventing foul-play data in an allowed action is much more problematic.
Ben S makes a great point about how you design the communication protocols between a client and a server like this. Allowing point values to be sent as trusted data is generally going to be a bad idea. It's preferable to indicate that an action took place, and let the server figoure out how many points should be assigned, if at all. But sometimes you can't get around that. Consider the scenario of a racing game. The client has to send the user's time and it can't be abstracted away into some other call like "completedLevelFour". So what do you do now?
The token approach that Ahmet and Dean suggest is sound - but it's not perfect. Firstly, the token still has to be transmitted to the client, which means it's discoverable by the potential attacker and could be used maliciously. Also, what if your game API needs to be stateless? That means session-based token authentication is out. And now you get into the deep, dark bowels of the Client Trust Problem.
There's very little you can do make it 100% foolproof. But you can make it very inconvenient to cheat. Consider Facebook's security model (every API request is signed). This is pretty good and requires the attacker to actually dig into your client side code before they can figure out how to spoof a reqeust.
Another approach is server replay. Like for a racing game, instead of just having a "time" value sent to the server, have checkpoints that also record time and send them all. Establish realistic minimums for each interval and verify on the server that all this data is within the established bounds.
Good luck!
It sounds like one component of your game would need request throttling. Basically, you keep track of how fast a particular client is accessing your site and you start to slow down your responses to that client when their rate exceeds what you think is reasonable. There are various levels of that, starting at the low-level IP filters up to something you handle in the web server. For instance, Stackoverflow has a bit in the web application that catches what it thinks are too many edits too close together. It redirects you to a captcha that you need to respond to if you want to continue.
As for the other bits, you should validate all input not just for its form (e.g. it's a number) but also that the value is reasonable (e.g. less than 100, or whatever). If you catch a client doing something funny, remember that. If you catch the same client doing something funny often, you can ban that client.
Expanding on Ahmet's response, every time they load a page, generate a random key. Store the key in the user session. Add the random key to every link, so that the new link to get those 100 points is:
increase_score.pl?amount=100&token=AF32Z90
When every link is clicked, check to make sure the token matches the one in the session, and then make a new key and store it in the session. One new random key for every time they make a request.
If they give you the wrong key, they're trying to reload a page.
I would suggest making a URL specific to each action. Something along the lines of:
/score/link_88_clicked/
/score/link_69_clicked/
/score/link_42_clicked/
Each of these links can do two things:
Mark in the session that the link has been clicked so that it wont track that link again.
Add to their score.
If you want the game to only run on your server, you can also detect where the signal is sent from in your recieving trick, and ignore anything not coming from your domain. It will be a real pain to tamper with your codes, if you have to run from your dedicated domain to submit scores.
This also blocks out most of CheatEngine's tricks.

Resources