How to get around server flooding by users opening countless tabs? - php

I have some kind of chat/forum application that checks for new messages using periodic polling (every 15 seconds) using jquery ajax. I was wondering if i can get around the issue of users who try to be 'funny' by loading several same browser instances, with lots of tabs, all pointing to the same application. Each tab is sending an ajax request, which potentially can overflow a server if several users start to do the same thing.
I do store sessions in a table, along with the last access time and IP address, which works fine as long as users don't use the same browser. I could store a unique identifyer that is sent using the ajax POST or GET request, but that would give problems if a regular (non abusing) user refreshes his page, which would then create a new identifyer.
This is not a real problem yet, but better catch it before someone thinks of abusing the system like this :) Any idea how to do this?

One option could be to fetch data like so:
Your script is preparing to poll data. Before executing the request, write (with LocalStorage), a value saying that you're going to fetch data. localStorage.setItem("last-request-timestamp", new Date().getTime());
Poll for data. You get a result. Write that result to the localStorage: localStorage.setItem("latest-messages", ajax_result);
Check if a page is preparing to poll data by checking if localStorage.getItem("last-request-timestamp") is longer than 15 seconds ago. If so, go to step 1. If not, wait 15 seconds and check again.
Regardless if the current page polled for data or not, check the latest-messages variable and update the page.
Other pages will of course share the localStorage data. They won't get data if another page is fetching at the moment. If page #1 is closed, one of the other pages will continue to fetch data.
I haven't used LocalStorage before, but browser support seems decent enough. You should also be able to just use it as a key-value array: localStorage["last-request-timestamp"].
You can only store strings in localStorage, but you can of course serialize it into JSON.

Not sure if it is do-able in javascript. You can check if the tab is active. And only do the ajax on the active tab?

I have the similar problem. Now I force all users to log in (it means i have their e-mails). Also i setup connections limit per account and request limit per connection, after 5 overflows i ask user to enter captcha, then i block account for a 30 min and send e-mail with password recovery link. It's not a clear solution but for now it works for me.
UPD:
The simplest way to do this is to use cookie or session storage. I use cookies. The algorithm is simple:
User login on web.
Check is there any opened session for this user,
is opened, then delete the other session or trigger exception or
switch to that session, you have decide your own the desired
behavior.
Create session id for user and store it in database.
Increase sessions counter field for specific user to detect opened
sessions, so now it doesn't matter is there one browser in use
or many.
Update last access mark (i use microtime(true) + $delay and mysql
decimal(14,4)). Send it to user
Send id to client
On each request:
Search for session by passed id in $_COOKIE.
Check last access mark. If it less then microtime(true) it means that client send requests to frequent, so decide yourself what to do, increase the mark, for example microtime(true) + $delay + $penalty or drop whole session or trigger error. The behavior depends of your application.

Why not throw something like Memcached/Redis at the problem? Cache a response with a 10-15s lifetime and avoid as much processing as possible.

Related

Check if active PHP session when user returns to a page - JQuery

I have an app where a user absolutely must be logged in to use it.
I use PHP sessions upon login to store user data.
If a user leaves a window open and then returns e.g. an hour later, what's the best way to check if they are logged in still?
Options I can think of are:
1) check mouse movement which then fire AJAX php file to see if session still active
2) check as above on mouse click anywhere
But these will then be running constantly and therefore hitting and hitting the server potentially thousands of times a second with not so many users, so I doubt efficient.
Is there a better way to do this? Is there a 'standard'?
I am using PHP and JQuery.
Use Javascripts setInterval(function, time) function to poll the server every X number of minutes to check if the user is authenticated. Return a response in JSON based on said result.
See javascript setInterval for a good discussion about the setInterval() function.
If you are in fact asking about a user being active on the website, you could use the setTimeout() function after X amount of minutes (such as an hour) to log the user out via AJAX request, or display a warning such as the ones in online internet banking.
If a user makes a request before the timeout occurs then this process is restarted naturally due to the request - response cycle.

PHP Concurrent Requests Lead to Multiple Sessions

I am working on a updating an existing visitor tracking script on a high traffic website. I noticed that there is a problem not with the script itself, but with what happens when there are multiple requests. Let's say a user double clicks on certain links to my site and there end up being two requests made at effectively the same time. Request 1 gets processed and a session is created. The script then proceeds to add a visitor record to the database. At the same time, request 2 is getting processed. It checks whether a session is set and there isn't, so it does the same thing as request 1 does. Now, we have 2 different sessions and 2 records in the visitors table in the database, when there should really be one. The session id for the current session ends up being from whichever request finished last.
So, what I'm looking to do is to prevent this from happening. Even if there are 100 multiple concurrent requests from the same visitor, I want there to be only one session id created and above all, only one record (not 100 records) inserted into the visitors table in the database. This involves determining in a matter of a few milliseconds that one request was already made. Any ideas?
You can set the beginning of your script to force a specific session. http://www.php.net/manual/en/function.session-start.php
I have the following workaround for my java application. When first accessing the php server I send a blocking ping call that establishes the unique session id. Afterwards I start my concurrent requests to the php server. This should also be possible from a web page for example in an init block.

Log what page the user is currently on

I have a chatroom on my website. I want to compile a list of online users in the chatroom.
What is the best way to do this?
Would it be to log the last page the user visited and if it was that page, they are in the chatroom?
What different techniques can be used to do this?
Thanks
If you're using Comet in your chat application, then you'll have a channel open to the server, which would be bound to the client side as an open HTTP request.
As long as that request is open, the user is in the room. If the request closes, then the user is no longer in the room.
I would use sessions javascript library to record each page the user has visited and then retrieve those values in your chat client via javascript.
include the library on each page.
in the sessvars object, make an array sessvars.visited = []; [if sessvars.visited is not already an array]
Now on each page do something like this sessvars.visited[] = location.href
On the chat client page, use javascript to iterate through sessvars.visited to obtain all the URLs. For example, To list out the URLs in HTML w/ Jquery do the following:
var urlList = '';
$.each(sessvars.visited, function(key, value){
urlList += value + '<br />';
})
Note: Sessvars is an alternative to Cookies that has a very large capacity (10mb in most browsers). However, session data is only available in an active window. Information is lost once the window is closed, and as far as I know cannot be queried from other windows. So if chat is open in a different window than they were browsing in, this will not work.
You should make a javascript request to the server every x seconds.
You already have to do this (for retrieving the ongoing chat conversation and the list of users participating).
On the server side you know what users are on because of this request. You just have to log these requests.
Yshout works by doing an AJAX request against yshout/yshout.php every 6 seconds. Add a bit of code to yshout.php to track how many unique users it's seen in the last 10 seconds, and you should be set.
Edit: you want the names of everyone active in the chatroom? I'd be tempted to add a database table for this - every time they hit yshout.php, add a name+timestamp entry and delete all entries more than 10 seconds old. Then query with GROUP BY name to get unique users.
Edit 2: The chat client already does an AJAX request on yshout.php every six seconds. All you have to do is add a snippet of PHP code inside the 'if (isset($_POST['reqFor']))' clause (the bit that responds to the AJAX requests).
Keep it brief! Remember, it's going to get hammered on something like 150 times per minute.

remove information from mysql table when user close his Browser

i m creating two table(in mysql) named
table_temp_guest
table_temp_order
now if a guest enters then we save his personal information in this first table and if he purchase something from any stall ,it saved as a temporary order in table_temp_order.
now my question is :
i m using session id, so when user goes to logout( without checkout) then
i delete his information(personal and order) from both table )using session id,
BUT if he close the browser, or does not go to checkout(any reson) then how
to delete his information from both tables
please suggest me how to do this?
additional question:
is there any other way to do this whole process by some other manner.
You can't detect when a user closes the browser or types in a new address. You basically need to have a "timeout" facility like the rest of the websites have.
There is a window.onunload event that you can detect with javascript, but it's not universally supported, and it detects window closes, not browser closes.
Your best resolution is probably going to be tracking the session_id and last accessed date. Re-update the table's last_accessed_date on every page load, and delete everything that's older than a few hours.
A timeout would be the best method.
Record the last active time in the guest table. Have a cron job running periodically on the web server cleaning up sessions that exceed the maximum time that you wish to allow.
Be careful about the amount of time that you allow. You have to allow for slow users and dropped connections.
If you're using session_id() anyway (I guess this is what you mean by session id), just use php sessions. PHP automatically invalidates them for you and you don't need those two tables (you can store everything you need in $_SESSION).
There is no way to check if the broswer wasn't closed you could rely on.
If you don't want to change the way your project works now, just add a created field to the tables and set it to the current time() whenever you're "seeing" the specific user. Then set up a cronjob which deletes all records from this table which are older than a specific timeout.
Also you can try to have a script that would run on the client side and ping the server so that you know if the script has not pinged for a while, the user closed the browser. That being said, I would agree with the previous posters, a timeout/ cleanup procedure would be best.
For that you would add a ModifiedDate field to your tables, you can set it as an "ON UPDATE" field for ease of use, then just delete all records that have an ModifiedDate field of older then several hours.

jquery - refresh the page when new data stored in to the table across the browser sessions

Environment : PHP/MySQL/Jquery
I would like to refresh the page (ex: index.php) when new data stores in to the table (ex : new_entry_table) checking for every one minute. The same page will be opened in many machines(pc-browsers) at a time all should get refresh when new data arises.
using jquery and database check i tried the following:
setInterval(function(){
$.post("new_data_check.php", function(data) {
if(data > 0){
$("#container").fadeOut('fast').load(location.reload());
}
});
return false;
},60000);
new_data_check.php: : checks
for new data in the test_db where
newdata_field=0 ; : If any new
data arises echo "1"; And update the
newdata_field=1; to stop constantly
refreshing the page. : else echo
"0"; : Just for a trigger
So the above jquery code checks new_data_check.php every 1 min for the trigger , if any trigger arises it will refresh the container.But its getting refresh only one opened session other opened sessions(in other browser or other pc) not getting refreshed.
Suggest a better way to do this. Thanks.
Your new_data_check.php file will need to keep track of all the users that are independently viewing the page.
If not, this will happen:
User 1 and User 2 are both logged into the site.
User 1 does the check 5 seconds before User 1, there is new data.
User 1 completes his request. The server clears the new_data bit.
User 2's request arrives 5 second later. Hedoes his request, but at this point, User 1 has set the new_data field to 0. His data is stale, but User 1 has effectively co-opted him.
By the looks of it, you're not supplying it with any information that would identify the user - unless the server is determining that using the IP address. If that's the case, remember that it's likely everyone behind a small network is going to have the same external ip address. So it can't tell people at an office apart.
What you could do is generate some kind of unique hash for each session and pass that off to the browser. The javascript can then provide the php script that same token.
Another solution without any sort of special bit, would be to pass along a timestamp with the request. Essentially, the client says "my latest bit of data arrived at 9:21:53 PM" The server then checks and responds "My most recent data was created before that, so you're still good. " or "I've got something that was created or modified on 9:22:53PM, you should download it."
With that method, you don't need to worry about who's who. Instead, you need to have modification/creation times on the data you're checking for staleness. You also need to make sure that the clients clock is synchronized correctly - better yet, don't trust the clients date and time information. Maybe utilize your new_data_check.php to provide the script with a timestamp it can pass along on subsequent requests.

Categories