As the title says, is there another way to pass a variable from "current" page over to "next" (new HTTP request) page without using sessions/cookies/$_GET?
Well, I guess $_POST could be an option too, but the thing here is, that I want to pass this variable from already executed $_POST back to off-the-post environment page, but inbetween I'm having a redirect, to disallow reposting the same form.
In other words, basicly, I'm trying to "make" a seamless PRG, but sessions/cookies/$_GET is not an option.
And yes, I'm working with classes (hence the oop tag). Therefore maybe some kind of magic functions, or output control?
This has to work within PHP environment, no JavaScript or other non server side language.
I also have a bad feeling that it's impossible, but hopefully I'm wrong, and there is a solution.
Thanks in advance!
update no. 1
Basicly, I want to create a PRG with response.
Inside this $_POST I'm adding data to database. I want this response to hold information whether this database query has been successful or not. Kind of make this $_POST process almost invisible to the user. And yes, display a response with the result later on.
All of this happens in one method:
if($_POST){
// insertion
}else{
// display no-post environment, if response exists (therefore posted) display response too
}
Something like that...
Sessions is not an option because this is meant to be some kind of API.
update no. 2
Huh, let me rephrase the question a little. Well, it seems that I don't actually need to pass the variable over. What I want to do, is to have 2 different results after POST so on next page load I could know whether the actions in POST has been successful or not. So, what other options are out there without using sessions/cookies/$_GET to get this result?
Currently there is:
temporary database usage: a good option, but I'd like to see different options;
Since you're already using a database it seems like the easiest way to handle this would be to update some kind of temporary table with the information you want based on the post call, then on the page you're doing a header redirect to, read the information in that table. With the constraints you've placed on this (no GET, SESSION, Cookie or Javascript) you're not going to be able to maintain a variable when you redirect from one page to the next.
So leverage that database and take the work off of PHP. Initially I was going to suggest utilizing cURL but I don't think that will help here (though you may want to look it up if you're unfamiliar with it, as it might be what you're looking for)
HTTP is a stateless protocol; thus, there's not going to be an easy, built-in way to add state. That said, I think sessions are the best way to accomplish what you want to do. If what you're doing isn't in the browser, maybe try some sort of session key setup (like the Facebook platform uses).
Related
Quick question, I have tried figuring this out myself, but the use of Session Variables can be confusing when trying to figure out why or how a page is reloading and doing/not doing what it is supposed to do.
Does a page reload (with JavaScript, f5, ctrl+f5, browser reload button, etc) ever, under any (non-scripted) circumstance cause a form repost?
(This pertains to using IfPost branches within C# code like the example code below):
if(IsPost)
{
//stuff that only executes if the previous request was a post.
}
I just kind of need to know what to expect here so I can properly diagnose my session state problems.
Thanks for any help!
(Also, sorry if I am oversimplifying this question. I realize that it 'may' be more complicated than a simple answer can provide).
******UPDATE**********
Also, I looked for copies of this question here, on StackOverflow, but I didn't see anything, so if this is a duplicate question, I apologize.
Both of the answers here are good answers. I accepted the answer that also offered a solution to my question, and while PRG is not the 'only' way to do it, it seems like it may be the best. It also seems a growing way to handle client-side user-friendliness, and imho, seems like it would be a great habit to get into.
Thanks for showing me that!
Yes. If the page was loaded using POST data this will occur. To prevent this you need to implement the POST/REDIRECT/GET pattern.
Post/Redirect/Get (PRG) is a web development design pattern that prevents some duplicate form submissions, creating a more intuitive interface for user agents (users). PRG supports bookmarks and the refresh button in a predictable way that does not create duplicate form submissions.
Yes. If someone refreshes the browser manually, it will ask them if they want to send the form data again. This will cause that code to get executed.
A way to handle this is using tokens.
Send a random string along with the post data
Store this random string somewhere
When you check the post data make sure that the stored string is the same as the string in the post request.
If true, handle the request.
Generate a new token
If someone were to refresh and resend the post data, your token in the post request will be different from the one you stored separately since you generated a new token at step 5
I asked a similar question before, and the answer was simply:
if JavaScript can do it, then any client can do it.
But I still want to find out a way do restrict AJAX calls to JavaScript.
The reason is :
I'm building a web application, when a user clicks on an image, tagged like this:
<img src='src.jpg' data-id='42'/>
JavaScript calls a PHP page like this:
$.ajax("action.php?action=click&id=42");
then action.php inserts rows in database.
But I'm afraid that some users can automate entries that "clicks" all the id's and such, by calling necessary url's, since they are visible in the source code.
How can I prevent such a thing, and make sure it works only on click, and not by calling the url from a browser tab?
p.s.
I think a possible solution would be using encryption, like generate a key on user visit, and call the action page with that key, or hash/md5sum/whatever of it. But I think it can be done without transforming it into a security problem. Am I right ? Moreover, I'm not sure this method is a solution, since I don't know anything about this kind of security, or it's implementation.
I'm not sure there is a 100% secure answer. A combination of a server generated token that is inserted into a hidden form element and anti-automation techniques like limiting the number of requests over a certain time period is the best thing I can come up with.
[EDIT]
Actually a good solution would be to use CAPTCHAS
Your question isn't really "How can I tell AJAX from non-AJAX?" It's "How do I stop someone inflating a score by repeated clicks and ballot stuffing?"
In answer to the question you asked, the answer you quoted was essentially right. There is no reliable way to determine whether a request is being made by AJAX, a particular browser, a CURL session or a guy typing raw HTTP commands into a telnet session. We might see a browser or a script or an app, but all PHP sees is:
GET /resource.html HTTP/1.1
host:www.example.com
If there's some convenience reason for wanting to know whether a request was AJAX, some javascript libraries such as jQuery add an additional HTTP header to AJAX requests that you can look for, or you could manually add a header or include a field to your payload such as AJAX=1. Then you can check for those server side and take whatever action you think should be made for an AJAX request.
Of course there's nothing stopping me using CURL to make the same request with the right headers set to make the server think it's an AJAX request. You should therefore only use such tricks where whether or not the request was AJAX is of interest so you can format the response properly (send a HTML page if it's not AJAX, or JSON if it is). The security of your application can't rely on such tricks, and if the design of your application requires the ability to tell AJAX from non-AJAX for security or reliability reasons then you need to rethink the design of your application.
In answer to what you're actually trying to achieve, there are a couple of approaches. None are completely reliable, though. The first approach is to deposit a cookie on the user's machine on first click, and to ignore any subsequent requests from that user agent if the cookie is in any subsequent requests. It's a fairly simple, lightweight approach, but it's also easily defeated by simply deleting the cookie, or refusing to accept it in the first place.
Alternatively, when the user makes the AJAX request, you can record some information about the requesting user agent along with the fact that a click was submitted. You can, for example store a hash (stored with something stronger than MD5!) of the client's IP and user agent string, along with a timestamp for the click. If you see a lot of the same hash, along with closely grouped timestamps, then there's possibly abuse being attempted. Again, this trick isn't 100% reliable because user agents can see any string they want as their user agent string.
Use post method instead of get.Read the documentation here http://api.jquery.com/jQuery.post/ to learn how to use post method in jquery
You could, for example, implement a check if the request is really done with AJAX, and not by just calling the URL.
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
// Yay, it is ajax!
} else {
// no AJAX, man..
}
This solution may need more reflexion but might do the trick
You could use tokens as stated in Slicedpan's answer. When serving your page, you would generate uuids for each images and store them in session / database.
Then serve your html as
<img src='src.jpg' data-id='42' data-uuid='uuidgenerated'/>
Your ajax request would become
$.ajax("action.php?action=click&uuid=uuidgenerated");
Then on php side, check for the uuid in your memory/database, and allow or not the transaction. (You can also check for custom headers sent on ajax as stated in other responses)
You would also need to purge uuids, on token lifetime, on window unload, on session expired...
This method won't allow you to know if the request comes from an xhr but you'll be able to limit their number.
Alright, so I've looked at a ton of questions, but I only found 1 that resembled what I am trying to do. Here is the link to it: Passing POST data from one web page to another with PHP
I want to pass data from one PHP file(we'll call it editData.php) to another PHP file(we'll call it submitData.php). Neither file has any HTML elements (pure PHP code I mean). The first file(editData.php) receives $_POST data, edits it, and needs to send it to the second file. The second file(submitData.php) needs to be able to read in the data using $_POST. No sessions nor cookies can be used I'm afraid.
In the linked question above, the answer accepted was to create hidden fields inside a form and POST the data from there. This worked for the OP because he had user interaction on his "editData.php", so when the user wanted to go to "submitData.php", he would POST the data then.
I can't use this solution(at least, I don't think I can), because I am accessing (and sending $_POST data to) editData.php from a javascript AJAX call and there will be no user interaction on this page. I need the modified data to be POSTed by code, or some other way that does the transfer 'automatically'(or 'behinid-the-scenes' or whatever you want to call it). submitData.php will be called right after editData.php.
I don't know if I can rewrite submitData.php to accept GET data, so count that out as well (it's a matter of being able to access the file). I really don't want to echo stuff back to my original JavaScript function(and then AJAX again). I am encrypting info in editData.php, and (while it sounds silly to say it) I don't want to make it easy for someone to develop a cipher for my encryption. Returning values after being encrypted(viewable with Inspect Element) would make it too easy to decipher if you ask me.
I feel like this issue could come up a lot, so I'd expect that there is something obvious I'm missing. If so, please tell me.
tl;dr? How can I send data to a PHP file via the POST method while only using code in another PHP file?
Well you might consider just streamlining your approach and including the submitData logic at the end of the editData file. But assuming that this is not possible for some reason (files live on different systems, or whatver), your best bet might be to use cURL functionality to post the data to the second script.
If the files are on the same server though I would highly recommend not posting the data to the second script as this will basically just double the amount of requests your web server needs to handle related to this script.
Normally I try to format my question as a basic question and then explain my situation, but the solution I'm looking for might be the wrong one altogether, so here's the problem:
I'm building a catalog application for an auction website that has the ability to save individual lots. So far this has worked great by simply creating a cookie with a comma-separated list of IDs for those lots, via something like this:
$_COOKIE["MyLots_$AuctionId"] = implode(",",$arrayOfIds);
The problem I'm now hitting is that when I go to print the lots, I'm using wkhtmltopdf through the command-line to request the url of the printout I want, like this:
exec("wkhtmltopdf '$urlofmylots' filename.pdf");
The problem is that I can't pass a cookie to this call, because Apache sees an internal request, not the request of the user. I tried putting it in the get string, but once I have more than a pre-set limit for GET parameters, that value disappears from the $_GET array on the target url. I can't seem to find a way to send POST data between them. My next possible ideas are the following:
Maybe just pass the sessionID to the url, and see if there's a way that I can use PHP to dig through the cookies for that session and pull the right cookie, but that sounds like it'd be risky security-wise for a PHP server to allow (letting one session be aware of another). Example:
exec("wkhtmltopdf '$urlofmylots?sessionId=$sessionIdFromThisRequest' filename.pdf");
Possibly set a session variable and then pass that session Id, and see if I can use PHP to wade through that information instead (rather than using the cookie).
Would I be able to just create an array and somehow have that other script be aware of it, possibly by including it? That doesn't really solve the problem of wkhtmltopdf expecting a web-facing address as its first parameter.
(not really an idea, but some reasoning) In other instances of using this, I've just passed an ID to the script that generates the markup for wkhtmltopdf to parse, and the script uses that ID to get data from the database. I don't want to store this data in a file or the database for the simple purpose of transferring data from the caller to the callee in this case. Cookies and sessions seem cleaner since apache/php handle memory allocation for these sessions.
The ultimate problem here is that I'm trying to get my second script (referenced here by $urlofmylots) to be aware of data available to the calling script but it's being executed as if it were an external web request, not two php scripts being called from the web root.
Can anyone offer some insight here?
You might consider rendering whatever the output of $urlofmylots?lots=$lots_to_print would be to a temporary file and running wkhtmltopdf against that file.
Using PHP.. I have a small app that I built that currently uses a querystring to navigate and grab data from a database. The key in the database is also in the string and that is not acceptable anymore. I need to change it. I would like to hide the db key and use a session in place of it but I'm not sure how to do that. In fact, there are also other variables in the query string that I would like to use sessions for if at all possible.
page.php?var1&var2&id=1
This is what my string looks like. I am looping through the results in the database and have given each row the id so that when the user clicks the row they want, but I'm not sure how I could do this with a session.
Does anyone have any ideas?
Thanks
EDIT:
I'm developing an email type system where senders and recipients are getting and sending mail. Each piece of mail that is stored on the server will have its own unique key. Currently, I am using that number to retreive the message but the problem is that I don't want people to change the number and read other people's mail. I can probably use a GUID for this or even some sort of hash but I really hate long query strings. I was just thinking it would be so much cleaner if there was a way to "hide" the id all together.
UPDATED (Again ... Yeah, I know.)
Allowing access to a particular set of data through a $_GET parameter is much more accessible to any user that happens to be using the application.
UPDATED
For storing a private record key, you are probably going to want to use post data, and if you really want it to look like a link, you can always use CSS for that part.
Honestly, the best way to stop people from reading other people's mail is by having a relationship table that says only X person is able to access Y email (by id). That or have a field that says who is the 'owner' of the email.
The fact is that users can still get access to POST parameters, and can easily forge their own POST parameters. This means that anyone could realistically access anyone else's email if they knew the naming scheme.
In an ideal system, there would be a Sender, and a Recipient (The Recipient could be comma separated values). Only the people that are on one of those columns should be allowed to access the email.
How To Use Sessions (From Earlier)
First start off with calling session_start(), and then after that check for variables from previous scripts. If they aren't present, generate them. If they are, grab them and use them.
session_start();
if(!isset($_SESSION['db_key']))
{
$_SESSION['db_key'] = // generate your database key
}
else
{
$db_key = $_SESSION['db_key'];
}
Sessions are stored in the $_SESSION array. Whenever you want to use $_SESSION, you need to call session_start() FIRST and then you can assign or grab anything you like from it.
When you want to destroy the data, call session_destroy();
Also check out php.net's section on Sessions
Your question isn't too clear to me, but I understand it like this:
You need some variables to decide what is being displayed on the page. These variables are being passed in the URL. So far so good, perfectly normal. Now you want to hide these variables and save them in the session?
Consider this: Right now, every page has a unique URL.
http://mysite.com/page?var1=x&var2=y
displays a unique page. Whenever you visit the above URL, you'll get the same page.
What you're asking for, if I understand correctly, is to use one URL like
http://mysite.com/page
without variables, yet still get different pages?
That's certainly possible, but that means you'll need to keep track of what the user is doing on the server. I.e. "user clicked on 'Next Page', the last time I saw him he was on page X, so he should now be on page Y, so when he's requesting the site the next time, I'll show him page Y."
That's a lot of work to do, and things can get awkward quickly if the user starts to use the back button. I don't think this is a good idea.
If you need to take sensitive information out of the URL, obfuscate them somehow (hashes) or use alternative values that don't have any meaning by themselves.
It completely depends on your application of course, if the user is accumulating data over several pages, Sessions are the way to go obviously. Can you be a bit more descriptive on what your app is doing?
Edit:
but the problem is that I don't want people to change the number and read other people's mail
If your primary concern is security, that's the wrong way to do it anyway. Security through obscurity is not gonna work. You need to explicitly check if a user is allowed to see a certain piece of info before displaying it to him, not just relying on him not guessing the right id.
There are some examples on how to use $_SESSION on php.
Registering a variable with $_SESSION
The issue with using sessions for using it in place of S$_GET or $_POST is that you need some way to read the user's input so that you can store it in the session, and you need a way to trigger a page refresh. Traditional means is via hyperlinks, which defaults to GET (unless you use Javascript) or forms, which defaults to POST.
Maybe ajax will help you here. Once the user has enter info into a form or a checkbox, use JS to send a request to insert the info to the PHP and send info back, whether it is to refresh the page or to fill a with content.
Hope this helps