I want to temporary store a series of array which will be used by next request. The stored information contains some sensitive data which will be used for navigating around that page with ajax call. The data were different from pages to pages. So, I just need to temporary store it for use when user is on that page.
First, I try to do it with cache: Cache::put($dynamickey, $multiArray, 20); But this will result in huge amount of "junk" cache store inside the folder even after it is expired.
So, I tried with session flush: Session::flash($dynamickey, $multiArray);. This works when user is open only 1 tab of webpage. But if user is open multiple tab of this website, it breaks.
For example:
1. User browse this website on tab1.
2. Then, user browse this website on tab2. As soon as after user browse website on tab2, the session data for tab1 is removed.
3. User come back and navigate tab1 content. The system break, and not working.
How can I store temporary data which will be deleted once it is no longer required, but also works well with multiple tab?
Thank you.
So, on the page that actually sets the session data you will need to generate a dynamic key which you can also generate when the ajax call is made. So:
Session:put($dynamicKey, $data);
Since the server doesn't know if you have multiple tabs open it just processes more requests, we need to distinguish AJAX requests from standard ones. This can be achieved via:
if (Request::ajax())
{
if (Session::has($dynamicKey)) {
Session::forget($dynamicKey);
// Do your application logic
}
}
So the session will not be removed until an ajax request is made where you can regenerate that key, now if you cannot regenerate that key from the data provided then you cannot tell apart two different requests. So you will need to get this key to the client side some how such as echoing it into a bit of javascript.
Now the AJAX call can utilise this key and send it in the request, where your server can pick it up and find the correct session of that tab.
Hope you understand this.
Related
I want to track and save to my local DB any event where my website's users click on links.
the user ID is saved in session information.
Links are structured like this: example.com/go.php?d=1234 , with 1234 being example for concrete link user want to go to.
Right now, on go.php, I use _GET and then redirect to user to the actual link (by searching another DB table to find the matching link for the d value, such as 1234.
I want the tracking to happen simultaneously, on server side only, in order to avoid slowing or undermining the redirection process of the user.
Therefore, my idea is to have go.php call another php script on my localhost - track.php.
And inside track.php do an INSERT with the user's data into another DB table, so if anything fails with the insertation, user will not be affected.
How can I pass data like the user's ID and the link ID that was clicked (and other info I plan to collect, such as user agent, resolution, referrer page, etc), under those requirements?
I can't use session since session are stored on the user's machine and I don't want user to have any interaction with this script, and even if session is stored on server, there can be multiple users who will click the same time on links and overwrite the session info I guess.
I don't want to pass info via a URL and use _GET to extract it, since I don't want to use an HTTP request, it makes no sense to use one (speed and security perspective), if everything should happen on my local host.
I don't want to use an include since like I said, if anything in the track.php code will fail, if it is included within go.php, this can cause fatal error and undermine the redirection process.
EDIT:
Is it possible for example to trigger track.php, the same way as cron jobs are triggered?
For example, If one can set a cron job like:
php /home/user/backend/track.php user_id=1 link_id=1234 user_agent="mozilla 1.7/85"
and pass parameters this way, so maybe in script I can do something like:
some-php-function(php /home/user/backend/track.php user_id=1 link_id=1234 user_agent="mozilla 1.7/85")
So maybe something like:
shell_exec(php /home/user/backend/track.php user_id=$u_id link_id=$l_id user_agent="$agent");
A short tutorial in W3schools about PHP Sessions writes the following:
When you work with an application, you open it, do some changes, and then you close it. This is much like a Session. The computer knows who you are. It knows when you start the application and when you end. But on the internet there is one problem: the web server does not know who you are or what you do, because the HTTP address doesn't maintain state.
Session variables solve this problem by storing user information to be used across multiple pages (e.g. username, favorite color, etc). By default, session variables last until the user closes the browser.
So; Session variables hold information about one single user, and are available to all pages in one application.
I would like to ask you if there is something similar in Zoho Creator. The reason why I am asking is because I have an application with 3 pages (each page has an embedded form). Each page redirects to the other (1st Page -> 2nd Page -> 3rd Page) and passes data through them via openurl. The final result is an HTML Page with the data of these 3 Pages (they have a unique ID).
Let's say that I am in the second page and for some reason (electricity blackout, do another job and close the browser) I want to escape from the application and the next time to continue from the same point, is there any way to do that??
I can suggest you next way
On first page generate unique session Id for the user and pass this id as a parameter to next page in URL. You can crypt in this id pointer to record from first form for example..
Let's suppose that you have a website that contains a single button.
When this button is pushed, an ajax request is sent to the server - who receives the request and adds 1 in an internal counter on its database.
An user could copy the entire request (and its headers) and create a script to send infinite requests to overload the server (and mess with the counter).
I'm trying to avoid:
Recording the user IP
Using Captcha
I'm using php in my back-end. Is there any way to prevent this situation? Is there some way to send an "invisible" request?
Your problem is called "cross site request forgery".
A good way to solve this problem is to generate a random string when the page with the button on it is called, write it into the users session and into the generated page, and send it together with your button press (for example in a GET request).
On the backend side you check if the submitted string matches with the string in the users session and then delete the string from the session. Only proceed if both strings matched and weren't empty.
This way every request URL is only valid one time and only valid for the user who initially opened the page with the button on it.
you can create a unique token that is assigned to the button and can only be submitted once with the button press.
this will mean that the user will need to refresh the page to get a new button, if thats a problem, associate the token with the user and not the button
the above method means that you need to add server side code. you might be able to get away with using something like evercookie to log the button press on the clientside and attempt to prevent the user from sending another request and recieving another request from user - i dont recommend doing this in prod, but it might be fun ;)
ill try to be bit more clear:
generate the button so that it submits a form containing a hidden field called 'uuid' that contains a pre-generated uuid for that button. this uuid will need to be kept in the database or in memory. if you use a good uuid lib, the chance of the user generating an existing uuid are infinitesimal.
now, the user clicked the button and the action goes to /my-button/?uuid=3394b0e0-a3bb-11e1-b3dd-0800200c9a66
now the server checks if the uuid is a previously generated one. if it is, it deletes the uuid from where its stored and lets the action do whatever. the uuid does not exist, it returns a 404.
You can't possibly know how a request is initiated, all you can do is make it more difficult to fake. But if this is something to do with security, then it's the people who can successfully fake the request that you need to be most aware of. So it's likely useless (or even misleading) to attempt this as some kind of security measure.
You can try an encrypted key that the server will only accept once within a certain time lmit, but you will still not know how the request was initiated (and you really shouldn't depend on that). Buttons are a UI feature that might be converted into some other UI artifact based on whatever the user agent has been configured to present to the user (if there is a user invovled at all).
I'm trying to transfer a large array between two sites in PHP. I'm the admin in both.
The array is created on one site, and after its creation I wish to automatically redirect the user to the other site, and pass the processed array along.
I cannot use the SESSION superglobal, as it is limited to a specific domain.
GET is not suitable, as the array is too long.
I'm not sure if POST is suitable, and if there is a way to automatically send the data without forcing to user to click a button and submit some form. I know javascript can be used for this, but prefer to have something more robust.
I'm relatively new to PHP, and would love to hear of any other ways of performing this.
Thanks!
The easiest way would be to use a HTTP library like cURL and setup and send a POST request to the other site. Also including the users IP address would allow you to associate the posted data. Without JavaScript you cannot redirect a user with POST data.
One thing you may want to be aware of with the above method is that depending on how it is implemented the user may arrive before the data does.
There is no limit on POST as defined in the HTTP specs, but you may run into issues handling it on your other server (depending on what you mean by large) depending on php configuration. (POST limit is I believe set to 8MB by default)
Send an HTTP POST request via cURL functions and add the serialize()ed array to the request body.
I'd do something like this:
generate a token on Server A (e.g. sha1(timestamp + session id + random()))
use cURL to post the serialized array to the Server B, passing along the token you generated
On Server B, store the serialized data and token in a database table - fields: token (CHAR), data (BLOB)
redirect the user to http://ServerB/?data_token=[TOKEN GENERATED IN STEP 1]
Server B fetches the data associated with the token from the db, deletes the db entry, and stores the array in the new user session.
Well, if they are both on the same server, you can have one hijack the others session. I have used this to jump to a secure server before, use the session_id() function on the first host to get the session, then use the same function to set it on the second host.
See http://www.php.net/manual/en/function.session-id.php
I would suggest that after you create the "Array" you associate it with an ID(and store somewhere) and then redirect to the other with this ID. From site 2 using the ID, you can call a page on site 1 which returns the "Array"
Your problem:
sent array(ar) From Server(a) to Server(b)
My solution:
Server(a) generates an unique url(url) for Server(b) which contains Array(ar) encoded in for example json using json_encode(ar). This Array(ar) should be stored at url using for example mysql or just a simple text file.
$uid = md5(uniqid(mt_rand(), true)); // to generate unique id
Server(a) redirects browser to Server(b) also containing $uid
$url = "http://server-b/page"; // url to page
header('Location: $url?uid=$uid');
Server(b) gets the content from url on Server(a) and decodes content back to Array(ar)
$uid = $_GET['uid']; // uid
$url_server_a = "http://server-a/webservice?uid=$uid";
$ar = json_decode(file_get_contents($url_server_a));
I guess you could serialize it, save it as a file that is accessible from the other server and load it again from the other server. That way, no user action would be required but you'd have to protect the directory where you save the file to avoid privacy problems.
Edit: I´m assuming they're on different servers, otherwise it would be even easier...
If it were me, I'd store the information in some other medium: a memcache type environment for example, or a database that both can access.
After the array is created you could quickly generate a page that has a form which contains the data in a hidden field. This page could then automatically submit the form (with method="POST") to your redirect.
You could decode the array into JSON and send a link to the second server, which contains the download for the temporary JSON file, just re-decode the JSON file back into PHP and you do not have to use LONG URLs.
I am trying to to solve a problem where I need to pass large arrays of data to another page, this is my scenario:
The user input his/her gmail login information inside a form, I then send this information to an ajax page where i authenticate and fetch all the contacts, if the login is invalid they can try again but if it authenticated I need to send them to the next page where I parse all the emails and check if they match any users on the site.
Method 1 (didn't work):
Store all the data inside a session, this only work if the array is small as there is a size limit for the sessions.
Method 2 (didn't work):
Add an hidden input with javascript and then submit the form (also with javascript).
As it turns out you can't submit the form and return true (change page) unless the user triggers the event.
So how should I go on, should I just skip the ajax authentication and send them back to the previous page if it didn't work or is there some workaround to my problem?
Why don't you store the data in a database, MySQL, or SQLite if MySQL is not available to you. In there, you would store a serialized version of your array linked to the users session id.
The MySQL table I'm thinking of:
id | session_id | data
http://php.net/manual/en/function.serialize.php on how to serialize your array.
If you are able to fetch the data again on the next page, you could do that instead of passing it between pages.
Since you are using jQuery you can submit the data directly or as a hidden element on the form without a user click. Assuming the second submission is via AJAX you can:
$("#mydiv").load("secondpage.php", {email1: 'blah'}, function(){
alert("Submitted everything nicely");
});
Depending on your webserver, but session variables do not typically have a size restriction. Apache+PHP you could handle extremely large sizes, instead you should care about
http://ca.php.net/manual/en/ini.core.php#ini.memory-limit. In addition, PHP.ini carries session.size variable that you could adjust. I am not sure how it did not work for you; you used $_SESSION, right?
Finally, to make a better persisting yet fast (faster than Database) volatile storage I would recommend using Danga's memcached. It is very stable, widely used and has wrappers for every possible language flavor.