Suppose we have a form where we allow user to submit some text or so.... Then the form is submitted which passes the value to another page where we show result based on the input submitted in previous page. Now we know both url so we may try to access them directly but first one is ok no problem, when going to acess second page it will not have the parameters or says the value to give result ?????? so i want to prevent user getting direct access to this page without filling the form and submitting same from first page.
Eg submit a form with text box name and next page we display details of that name from database. url may looks like for second page www.domain.com/page2.php?name=somename
Any Idea?
*we already checked user to login when try accessing the first page
Try this...
if(!isset($_GET)){
header('Location: http://www.backtoyourotherpage.php/');
}
But I would use POST on your form, so that the url isn't printed in the fashion that you showed....with all the words in it
then it will become ...
if(!isset($_POST)){
header('Location: http://www.backtoyourotherpage.php/');
}
This variable have the URL that calls the page..
$_SERVER['HTTP_REFERER']
You can check if there are data passed by $_POST or $_GET but the best method is generate an aleatory string (or token), save it in the $_SESSION variable and send it in the form, then compare twice, if them match continue the execution...
There are two ways you can test how the second page is being accessed:
The simplest one is that you will always check if you're getting the required POST parameters you're looking for in your second page. You can do that by checking that the required form values exist in appropriate fields in $_POST
You can also check for the page referer, and only allow access to page B if the user is coming from page A (however, do note that the page referer can be spoofed by clients). Here's an SO question describing how to obtain the referer in a PHP page
Use the following code at the starting of your 2nd php file. This will check if the url is requested as POST or not. Assuming you have the method POST in your form. This will prevent users from directly accessing via URLs.
<?php
if(!isset($_POST)){
header("location:someotherpage.php");
}
?>
This, however does not work when the user sends POST requests from any other place.
It's also good to check for individual form fields, and redirect.
Related
I have html page where you can insert some information and then submit this form, which will change information in database. I do it normally, that submit button call php file in server.
But what I want, is that this php file will return to me the same html page of which I sent request, with modified changes. e.g: there will be "Database update successfully" text added etc.
How can I do it without AJAX ?
Thanks
In the PHP file, do a call to the header() function to redirect the user. For example:
header('Location: url.php');
To change the content of that page they are redirected to, you could pass something in the URL that your page will check for. For example:
header('Location: url.php?submitted=1');
There are other ways to implement this, but this seems the most straightforward to me. Note that you don't want to call header() until the end of your submission page.
Use POST/REDIRECT/GET
Excerpt:
The user submits the form
This is pretty straight forward. The user completes the form and submits it by pressing the submit button or enter on their keyboard.
We store the form data in a session
After processing the data we discover an error so we need to redisplay the form with an error message but we also want to populate
it with their data so they don't have to refill the entire form just
to fix potentially one little mistake. So we store their data in a
session ($_SESSION). Session variables carry over from page-to-page
for as long as the session is valid or until they are deleted. This is
an ideal place to put their information since redirecting will cause
their information to be immediately discarded by the server.
We redirect the user back to the same page using a 303 redirect
Once we have saved the user's information in their session we need to redirect them back to the same page. In order for this to work
properly we need to use a 303 redirect. This means we need to send a
303 header with our redirect. A 303 redirect will cause the browser to
reload the page without the initial HTTP POST request to be
resubmitted. This includes when the user uses the back or refresh
buttons.
We re-populate the form using the data stored in the session
When the page is sent to the user we re-populate it with their information we saved in their session.
Only by generating the whole page in CGI first, unless you go through some horribly convoluted method of getting value of one of the fields to be set to document.innerHTML or something like that in Javascript. But you'll go through hell to get the quoting issues resolved. Use AJAX, it was created for precisely this purpose and exactly to avoid the utter hell associated with what you need.
Alternatively: the "modified piece" of the page may be an iframe, and you can set the target attribute of the form, so that the PHP returns only the iframe content.
Is there a way to avoid reprocessing forms when I refresh php pages? I'd like to prevent resending forms when refreshing links to php files with an insert function in them. For example, I am processing a series of notes written by users at the top of each page for a new note. Besides the obvious creating a separate php file with a header function is there another way to do it?
Use the Post-Redirect-Get Pattern.
Accept a Post request
Process the data
Issue a redirect response
Accept a Get request
Issue a 200 response
If you need to display data from the submitted stuff, then include a row id or similar in (for example) the query string of the URL you redirect to.
The best way would be to do a header("location: form.php"); call after you process the form. That would redirect you back to the form page, and if you refresh, the browser wont resend the form data.
Alternatively, you could check to see if you already processed the data received, but that would still give you the browser warning message that you are going to resend the data.
You might do both, just in case someone uses the back button and accidentally clicks Submit again.
Just set some flag when you process the form first time so you could check for it and abort reprocessing later on. Session variable or cookie will work fine.
You could put a nonce into the page that is only allowed to be used once so that if you see the same nonce come in you don't do the insert of the page.
I redirect users to a new page after processing of the form.
The form is a POST-request to do-something.php. I check the input data and if it validates I process the data and perform a redirect to do-something.php?somethingdone. So the user can hit F5 w/o resending the POST request.
I tried to use header("Location:..."), $_POST = array(), unset($_POST), but (idk why) they didn't work in my php page.
So, what I did, I just used
echo '< script>window.location.replace("http://.../this.php")</script>'
😂 it works very good! Maybe it is not a good idea, I am learning PHP for the 4th week.
I am using 9 checkboxes to get input from user and using POST method to get the data. The problem is that when I try to reload that page, the browser shows me this message-
"To display this page, Firefox must send information that will repeat any action (such as a search or order confirmation) that was performed earlier."
with 2 options, RESEND CANCEL. Please tell me what should I do. Can't use GET as it displays my whole search query.
If you are perform some search to get information, I recommend to just use GET. POST-REDIRECT-GET will also display your search query.
If you use post, the browser will confirm that you really want to do a post once more.
Use GET to get data, use POST to operate the data, in my personal opinion.
Quick and dirty: Store all the values of the check boxes in a $_Session[] array and check for that first.
if($_SESSION["CheckBox1"] === "on")
{
// Do Stuff
}
else
{
// Get $_POST[] Data and do stuff
$_SESSION["CheckBox1"] = $_POST["CheckBox1"];
...
}
When the user submits the Form you first check if the $_SESSION has data otherwise put data in it and go about your normal work. If a reload happens then the $_SESSION values are used and not the now empty $_POST array.
After posting the data, Redirect to the current page. That will cancel out the resend/cancel issue.
If your website is User-Profile based, you can have a look at the users data and return selected checked boxes.
OR
You can set a cookie value, via javascript [on checkbox click] or backend [when posting], this way you can store checked checkboxes and return it clicked on reload.
This only happen when you try to REFRESH page after POST Request.
Bowser asks you what should it do: resend POST data or simply refresh page without POSTING (send GET only).
The same behaviour on Chrome. Opera doesn't asks, just resend previously sent POST data by default.
Changed the method request type from POST to GET in my search form and got rid of the confirmation box..
Further to my previous question, here's what I decided to implement; it may not be pure P-R-G, but it seems ok. Care to comment?
The form.php has an action; let's call it validate.php.
validate.php is never seen by the user; if validates all $_GET and, if valid writes it to database and generates the HTML of a confirmation page / if not valid, it generates the HTML of an error page explaining what is wrong.
Whichever HTML is generated get stored in a $_SESSION variable and then validate.php does a header('Location: <as appropriate>);
Finally a page called submitted.php of invalid_input.php (in case the user reads the URL) consists only of echo $_SESSION['form_html'];
That seems to me like is proff against both page reload and back button problems.
Or did I goof by trying to reinvent the wheel?
Firstly, you're better off storing the form data, which means you can perform the validation again. It will also be less html. The problem with the method you're employing now is that it doesn't protect against multiple tabs, since $_SESSION is universal to a browser session.
One way I've used to prevent against duplicate submission (without PRG) is to generate a unique id for every page load (where a form is involved). When I generate that unique id, I add it to a $_SESSION['form_unique_ids'] array, and I include it as a hidden field in every form I generate. Then before I take action on a form submission, I check to see if that unique id is in the session. If it is, this is the first time that form has been submitted, and I remove it from the session. That way if I try to resubmit that page, I will know because that id is not in the session not to process the results.
This could be extended so that instead of storing a single id, you use the id as the key in the array, and let the value be the result of the transaction. Then:
If there are errors, you store the $_POST data as well. Then, redirect to original_form.php?id=unique_id and display the validation results. You can either store them or recalculate them there.
If there is success, store the success message and redirect to success_page.php?id=unique_id. Display the success message prominently there. If you like, you can remove it from the page.
You have the option of removing the session data when you display it, but that would mean if they refreshed the edit page they'd lose the validation messages and saved form data. I'd rather find a way to get rid of data that is old enough that they're not likely to need it anymore.
Anyway, some of those ideas might be useful. Then again, maybe it's way too much effort for the problem. Your call :)
As long as you use a php redirect at the end of your validate you cannot reload or back button into the validate.php
Well right now I have a page (page2.php) and at the top it does some validation checking and if something fails it bounces back to page1.php. The problem is that page1.php is loaded by a post meaning it is the end result of a form. This means that all the post data I originally have on page1.php is lost.
So here is my code:
if ($validation_fails)
{
header('Location:page1.php');
}
You can post data back with cURL or re-structure to do the validation at the top of page1.php and if it doesn't fail, take to page2.php. If you are doing some sort of multi-step form, you could save all the data in a session and populate fields if there's matching data in the session. Not sure if that applies, though.
You could restructure the logic. The validation should happen on page1.php and if it fails, the redirection does not happen. If it succeeds, you are redirected.
If you are concerned about safety (people just going to page2), you could set a session variable that is checked on page2 and set on page1.
Can’t you just include the validation script via include or require instead of redirecting to it?
On page2.php You could store the contents of the post into a $_SESSION variable if validation fails.
On page1.php you simply include a properly escaped/encoded version of the data that you stored in the session as part of the form. You would also be able to use this to update the form so it is clear the user what part failed the validation.