I have a PHP form, and I'm wondering how I should handle submission. I remember when learning Rails that the behavior was to have a special handler page for a form, which then redirected the user to a landing page, which would prevent the user from accidentally re-submitting data by hitting the back button and going back to the form submission page.
For my PHP form, to avoid such errors (and for secureness, however it might play in) is it also best to send the form data via post to a handling page, which they redirects the user? Or would it be ok to just handle the form data on the same page as the form? If I did the latter, is it possible for a user to accidentally resubmit data via hitting back/refresh/etc?
Post-Redirect-Get is the design pattern recommended for web-forms to prevent resubmission (and what you used in rails)
It doesn't really matter if you submit to the same page or a different one, it's the redirect which prevents the accidental resubmission. You can therefore choose whether to post to the same page or a separate page depending on your coding style and/or application semantics.
The same principles apply to PHP. Redirection can help against accidental form refreshing. However, you still should take whatever precautions are necessary to avoid problems from accidental refreshing (e.g., using single use tokens, validating the input, etc).
I use my own MVC style of framework that simply has the dispatcher look for form posts on every page view and calls the appropriate controller that can process the request (assuming the submit-only-once requirements were met). It then redirects the browser to the appropriate landing page.
You can post to the same page, of course, but I think it will lead to bad practices, such as mixing too much logic, html, and database access together.
There's a third way to go about this that I am particularly fond of. In an effort to separate logic from presentation, I like to include a PHP file with every HTML document that requires processing of some kind (such as displaying dynamic data, handling HTTP POST requests etc.). I generally store this file in a separate directory and name it "filename.page.php". Needless to say, this is nothing more than a coding convention and you may want to call it something else.
In a sense, this means you're handling the HTTP POST request in the same file (at least as far as your web server is concerned). You can redirect clients anyway, though, by using the HTTP Location header like so:
header("Location: file.php")
As a side note, I wouldn't depend upon HTTP POST for security; it is no harder to make arbitrary HTTP POST requests than HTTP GET requests.
Related
I am currently diving into php and html and working on a simple redirect just for the purpose of showing database content through an url.
I know you can generate an URL in 2 ways, probably more but these two are the reason why I started this question:
php:
<?php
header('Location: example.php?parameter');
?>
html:
<form action="example.php" method="post">
<!--input fields etc -->
<input type="submit">
But now I was wondering "What is the best practice regarding these two options". Is it just a personal opinion with what you like the best and what is the best suitable way in a situation or is there something else I am overlooking.
I am not trying to start a discussion here, just interested in what is 'normally/commonly' used.
Thanks in advance!
These two pieces of code do fundamentally different things, even though in some cases the user-observed behavior may be very similar.
This is a server-initiated redirect:
<?php
header('Location: example.php?parameter');
?>
Basically this is the server's way of telling the browser that it should browse to another location. (The browser can ignore it, but doesn't really have a reason to ignore it.) Additional details can be added to the response to tell the browser if this redirection is temporary or permanent, or has other conditions regarding it. But at its simplest this is just the server saying "I don't really have anything for you here, go over there for your information."
This is a client-initiated form POST:
<form action="example.php" method="post">
Well, "client-initiated" in that the actual action of POSTing the form comes from the browser. The server probably gave that HTML tag to the client to tell it to do that, but the client is free to change it if it wants. (There's no reason to do so, though.) The point here is that this is a means by which the client sends data to example.php. It has nothing to do with redirects, it's just sending data to a specific resource on the server.
The server can respond to that data with a redirect, or a rendered page, or any other response.
These might be used in conjunction in a number of ways. Let's say you have page1.php and page2.php. On page1 there is a form, and after that form is submitted you want the user to see page2. This is where the user-observed result might be indistinguishable.
page1 can post to page2 and page2 can handle the submitted data and then display. Or page1 can post back to page1, handle the submitted data, and redirect to page2. To the end user, there's essentially no difference. The main difference is in how you organize your code. In that regard, sure, personal preference comes into play. But this isn't the only scenario in which either of these tools are employed. For example, you might want to submit values to a completely different page for a completely different reason, or redirect on a page request for some server-side reason completely unknown to the client.
As you develop more complex web applications you'll find certain patterns work well in certain situations, and personal preference will begin to conform to those patterns. In the end, these are just tools to perform actions (redirect the client to another location, send data to the server) and your overarching patterns and practices simply make use of the tools.
The HTTP location header and a HTML form are not really comparable.
The header should be used if you want to create a redirect during the execution of PHP. The form should be used if you want to submit user input from the client side (browser) to the server side.
HTML anchors are the best way to provide links on a web page:
Click
In most cases you use html forms or links. header() is used mainly if you want to redirect an user after the code is executed (e.g. after a successful login, or when is not authorized to access a restricted page)
What is the best practice as such? I have an iframe with a form and when it submits it updates the parent page. Currently it sends the form contents via GET so the parent page url reflects this. I can do the same via POST, but am wondering if this is frowned upon and if sometimes this is blocked/ unuseable.
Any help and advice is welcomed
There are no problems caused by using POST across domains (at least none that you wouldn't get from using POST on the same domain or GET on a different domain).
There is no problem submitting a form to a different domain, unless via javascript.
One concern to keep in mind is validations. You would want to take care on what happens when the form has errors, as you wouldn't want them to loose the information they've typed in if they missed something like 'name'. The server should be the final line of defense for validations, but you'll want to make sure that the client side validations for your form match those of the server and appropriately notify the user of their (or the server's) mistake.
The other thing that could potentially block a form from submitting over post would be a form that requires an authentication token. These are used by many different frameworks to prevent CSRF (Cross-site request forgery) attacks and ensures that the form was submitted from the same website domain.
I am supposed to capture data from a form and send the data to a url on a different server.For eg:-I have a form on a page at the url http://www.form.com/register.php.
I capture all the data from this form and for some reason need this data to be processed on a page on another server at http://www.thereceivingpage.com/process.php.
As of now I am using headers to redirect with the parameters in the query string something like this:-Header(Location:http://www.thereceivingpage.com/process.php?name=alice&address=a1&address2=a2) but I need to send a larger amount of data which wont happen as GET request. Can anyone suggest a better way where in I can post data rather than the data in the query string ...thanks
Use cURL. If you have to redirect to the site, it gets a bit trickier but you can still do it. You can get the cookie and redirect information back from the site and then do a GET redirect using header.
Can you not update the action to simply post directly to that form? Otherwise, you might want to look into something like curl: http://ca.php.net/manual/en/function.curl-exec.php
You'll pretty much re-use the header redirect syntax with the parameters but instead you'll tell it to be a post.
redirect to a page on a different server and post parameters to it
thanks to internet standards, that's impossible.
if it's third-party site, let user to interact with it directly. do not interfere between them, it smells
If you want to develop secure applications then you should be aware that http://www.thereceivingpage.com/process.php is vulnerable to Cross-site Request Forgery (CSRF), meaning that anyone, from any site, can post form data to process.php.
process.php should be checking for a token (which www.thereceivingpage.com transmitted to the user as part of the form) and should be rejecting form submissions that don't contain the token to prevent submissions coming from anywhere but www.thereceivingpage.com and thus protecting your users from being manipulated into making requests they didn't want to.
In addition to your concern about the size of the GET requests you cause the client to make when redirecting, it's also not a good practice to turn POST requests into GET requests.
The best solution is to completely rethink the notion of delivering a form from one site to be submitted to a different site.
You can manually set headers and send request or you can use curl
see this
http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html
I know that Codeigniter has a very useful security class which can prevent CSRF/XSRF if you use the form helpers, but since the CI url structure calls a lot of functions pretty much directly, how can I prevent CSRF for things like /action/logout without having an additional confirmation form like SE has?
Ideas I've had:
Check page referrer
Check requested MIME type (even possible?) (for image CSRF such as <img src="http://example.com/action/logout" />)
Make all actions part of a form (not preferable)
Include the CSRF token in the page URL (ugly and very bad, users like to copy and paste urls without regard for session IDs stored or other private information)
I won't bother protecting things like /account/view/1/cyclone/ since it doesn't perform an action and would at most be a waste of bandwidth.
Granted, I do know that some people like to code things to automate their website usage and I respect that, which is why I'll be creating an API for performing actions via code or automatically.
As a general rule, any form request that performs an action should use POST. For all else GET is permitted. Using POST will definitely help. I believe you can also include the token as a hidden field in the form instead of an ugly string in the URL. As for checking the requested MIME type, this is not possible. Do a print_r($_SERVER) and in there is basically everything you get from the user as well as server side stuff.
If a user tries to log in and the login fails the page should display an error message to the user. There are two main ways I see to do this: use a form action on the HTML page and in the php script if the login information is incorrect redirect with header to the login page with a $_GET value like loginfailed. The login page would check for this value and if it exists it would display the error.
The second way I see to do this is not use a form at all and instead use JQuery to capture the submit button press and use AJAX to determine if an error occurs. The php file would echo back a status and the javascript file would interpret it and if it was loginfailed, it would use JQuery to append the error message on to the page.
Now I will go over what I feel the pros and cons of each method are.
Method 1 Pros:
Very simplistic with no need for JQuery, Javascript, and AJAX.
The error status is displayed within the URL as well.
Method 1 Cons:
Since there is a header call, a redirect is necessary. Also, the login page must be reloaded. It is a small page but it is a reload nonetheless.
The status message is displayed in the URL. This means that users can type in status messages in to the URL and receive error messages on the page for errors that did not actually occur. Is this a problem? Maybe. Maybe not.
Method 2 Pros:
Since it is using AJAX, there is no need to load another URL and thus, no extra page is loaded.
This method uses JQuery to update the page with the error message so no redirect is necessary.
The error status is not displayed in the URL.
Method 2 Cons:
Much more complex than the first solution.
An external javascript file is needed and must be loaded every time the login page is accessed regardless of whether or not it is used.
The default behavior of the submit button is overridden and annulled. Its only behavior comes from its interaction with the javascript file.
What would SO do? I would like to stay away from answers such as "it depends on how much traffic your site would have" if that would be at all possible.
Always use the simplest solution possible until/unless there's a very good reason to do otherwise. It's better to finish something that's maybe (and maybe not) less than ideal than to deliver something gold-plated eventually, maybe.
Also, I generally prefer to follow a progressive enhancement strategy, such that everything works without Javascript, and then add Javascript to make it work in an improved manner. This has the added benefit of being functional, even when/where Javascript is disabled.
I think you fail to grasp the matter.
Login is not something self-sufficient. It is used to change state of the site. But with no reload it will not be changed. So, page reload is required anyway. or user will have to do it manually to get access to the authorized section.
Is login the only site feature that uses JQuery/AJAX? If not - why you're worrying about loading this library once, when most likely it will be loaded at every page?
There are still clients with JS disabled, for various reasons. A good web application will always let these clients in, even at cost of less functionality.
The latter is the main question, most important one. Why to choose between two? Why not to use both? - one for compatibility and another for usability?
So, I'd suggest to create basic functionality using GET to pass come codes, not messages.
And optionally improve it with some AJAX bells and whistles but with JS-based reload on succesful login anyway