Proper way to process forms - http

What is proper way to process forms in http?
on /somepage:
<form method="POST" action="/someaction.html">
<input type="text" name="name">
<input type="submit">
</form>
Let's assume, that user didn't filled in "name". So I should produce some error. How should I do it:
First method
POST /someaction and 302 Redirect to /posterror?error=1
GET /posterror?error=1 and 200 Ok with content about errors and form
Second
POST /someaction and 200 Ok with content about errors and form
Third
POST /someaction, remember in session form errors and 302 Redirect to /posterror
GET /posterror and 200 Ok with content about errors and form
Which one is proper way? Maybe some fourth one?

The correct approach is called post/redirect/get and is described by wikipedia as:
Post/Redirect/Get (PRG) is a common design pattern for web developers
to help avoid certain duplicate form submissions and allow user agents
to behave more intuitively with bookmarks and the refresh button.

The third one. It allows the user to safely hit refresh or bookmark the page. The first one, although similar, would require you to pass the content of form back and forth over the wire, which is inefficient. As slight refinements, you might consider:
Redirect back to the form, not to a separate error page, to give the user a chance to correct their error
Rather than just storing the error data in the session, store it with some unique id, and then include that in the redirect url. That way the user can can have the page open in two browser windows and they won't tread one each other's toes.
Expire the stored error after a set length of time, or when the form is finally correctly submitted.

I would suggest having some sort of validation before the for is sent using javascript.
Then of course you should validate the form input on the server side as well. As for whether to use redirects, I don't know of any de facto standard there.
If you want to follow use the HTTP protocol as it was meant you should probably send a 4xx status code back (e.g. 400 bad request) with an informative message saying what was wrong in the input.

Is utilizing client-side validation out of the equation? Using javascript you can avoid posting the form (and reduce server-side processing) and let the client (user's end: browser) perform the validation. What other validations do you have in mind?
Here's a link to basic validation that you can apply using javascript:
http://www.w3schools.com/js/js_form_validation.asp

Related

handling DELETE in REST

I have the resource uri as /avl/leagues/leagueName. Idea is to delete the league with the provided name in a restfull way. I tried the below but the browsers are always sending a GET instead of the DELETE. Any ideas why? I am using Tomcat on server side.
<form action="/avl/leagues/Cccccc" method="DELETE">
<input type="submit" value="Cancel league">
</form>
HTML forms only officially support GET and POST for submitting.
Typically, people work around that limitation by either sending the request via Ajax, or including a hidden field in the form to tell the server-side code to treat this request as if it were a DELETE rather than a GET. (Of course, the server-side code has to know to look for that field and act accordingly.)
Browsers are not very good restful clients. They basically use POST and GET for forms, and that's all.
The Spring MVC form tag library allows specifying DELETE as the method, IIRC, and will in fact add a hidden field to the form telling the server that, although the method is not really a DELETE (because the browser is not able to send such requests), it should be treated by the server as a DELETE (thanks to a filter). See Using PUT and DELETE methods in Spring MVC for a similar question and its answer.

header file reload again and again in jsp

My All Js and css are in script.jsp file and include on every page
<jsp:include page="../include/scripts.jsp" />
when page submit / refresh it reload again and again ?
How to control this ?
Here's an explanation I found that could explain it. It helped me out when i needed it
Here's an explanation of the problem...
Clicking the "submit" button on a form sends a request to the web server, which includes all the data entered on the form. Not only the URL but also the form data is part of the request, and this request is remembered by the browser. If the user clicks "refresh", the browser repeats the request, sending the same URL and form data to the web server again.
But forms can be submitted in two different ways, GET or POST, depending on the "method" attribute of the "form" tag. There is a convention that a GET request has no side-effects; it only fetches data but does not make any changes to the database. On the other hand, if a request changes data it should always use a POST request. As I said, these are only conventions, and there is not much technical difference between them, but a very important difference is that browsers will warn the user if they try to repeat a POST -- clicking "refresh" will pop up a dialog box warning the user that this may cause an operation to be repeated, and confirming that they really want to resubmit. The browser does not show this confirmation when refreshing a GET request.
Is your form using the GET method changing it to POST is the simplest solution, since this will at least mean that the user is warned if they try to refresh.
But a better solution is the POST+REDIRECT+GET idiom suggested by #cletus. This splits the database update (POST) and the view (GET) into two operations. Clicking refresh on the browser then merely repeats the GET, which has no side-effects.
Use the include directive <%# include/> as against the <jsp:include/> tag you're using now.
<jsp:include/> will instruct the jsp runtime to go and fetch the included resource everytime the compiler comes across that tag (first-time requests, refreshes) while <# include/> means that the included resource is built into the parent resource at compile-time
The difference is that the directive is a compile-time include. This means that the content of the directive (in your case scripts.jsp) is baked into the parent jsp (and ultimately the servlet that the jsp will be compiled into). The effect is that the included file is read only the first time the parent jsp is rendered.
What you should have:
<%# include page="../include/scripts.jsp" />
Related:
What is the difference between <jsp:include page = ... > and <%# include file = ... >?

Is javascript reliable for preventing actions on the front end such as form submission?

I have a webservice that I need called, the result of which determines whether or not the user is allowed to submit the form.
Since this call is from javascript and not from code behind is it not reliable? Is there any way the user can get around the check -- by either going in with firebug and enabling the submit button, somehow making the method give a different result than was actually returned by the webservice, any other ways of being able to get around it?
Basically is there any way to call a webservice from javascript and have it's result determine whether or not a form can be submitted, and actually prevent the user from submitting the form at all? -- whether or not they have firebug, etc...
No, not possible.
Just to name a few possible reasons:
what if javascript is disabled?
what if the user submits the raw POST (using libcurl, for example)?
what if the browser, that the user is using interprets javascript in a way, different from your expectations (think, portable devices)?
Javascript validation is there for your users' convenience only and should never ever be used as a means of providing security.
You can never prevent the user from making an HTTP request that mimics submission of the form. While disabling the form via Javascript prevents submission for 95% of the users who both have Javascript enabled and don't want to circumvent your access control, anyone who understands HTTP can make the call and you are correct in showing that anyone with Firebug can do it in a matter of seconds.
Javascript isn't reliable for preventing anything. It shouldn't be seen as a security-wall, as it's too easily disassembled with things like firebug, iedevelopertoolbar, and many other browser toys.
Even if you could prevent them from submitting your form on your page, nothing stops them from creating a brand new form, on their own page, and point it toward the action of your form. Thus they're removing themselves from your "secure" environment, and instead chosing to play in their own.
Your suspicion is correct; the user can easily get around any possible Javascript validation.
You will need to use server-side code.
No, it is not reliable. Try disabling Javascript in your browser to see for yourself how easily you can get around it.
The user could simply disable javascript in their browser, or use something like NoScript. The best you could do is to try setting the form action itself in the return from the Ajax request, that way the form, as loaded, won't submit (except to itself). This will probably stop casual users but would be no impediment to a slightly more determined (or just bored and tech savvy) user. You will need to check on the server side whatever you do.
In general, no. You can make the form hard to submit without going through Javascript. Make the submit button not an actual submit button (<input type="submit">), but a pushbutton (<input type="button">) that submits the form in its onClick handler.
As everyone else said, no you can't do it. The only real solution is to have the web service return some dynamic value which the Javascript inserts in a hidden form input. Then whatever server-side code processes the form submission should reject the request if that value is not present.

can i repost or carry POST data (if so, can i do it with redirects?)

I want to redirect the user to another page to fill out a captcha but i would like to keep the post data, and if the captcha pass to send it 'back' and complete the previous page action.
When/if the user succeeds i like to add an captchaPass=true and would like access the post data and continue processing. Right now i am using redirects but ATM i am not required to use it.
Is it possible to carry the post data? keep in mind i may the user access multiple pages so separating data and not having a mixup is necessary.
One idea is to get and save all posted data [1] on the captcha page, and then recreate a middle white page with this form data and automatically make a new post to the previous page.
Can this work with out any issues with hash checks and security ?
Is there a better idea with out this white redirect page ?
[1] One other issue here, how to send this posted data with the redirect ? and not change the url - or make it too big to accept it. Keep in mine that a server transfer may not good idea because is complicate the thinks on captach post back.
Update 1
The basic idea here is how some one capture the full post back of a page, show a different one page and then send the post back data to the original first one.
The reason is to stop a bad user, or an attacker bot program that try to bring down the pages/server by making many post back from different pages in short time. All that happens with out javascript, and most attackers use custom made programs that just make post of data to all page together try to bring down the system.
For example, if a page have a search box, is very easy for most of the the site to bring them down by start making hundred of random search with wildcard (called and Dos Attacks using SQL wildcards) and make the sql server and the computer spend his time and cpu to search and search thinks. So to prevent an attack like this you need to recognize multiple post backs from the same computer, and then the next step is to redirect him to a captcha page to block him out in case that is a computer program.
Other example, many page have email submit, very easy you can submit hundred times the email of his and full his mail box in no time with hundred of emails, or on a store to place all items on the cart again and again and full the database with stuff like that.
So ajax and javascript is not working in this case, and we need a way to redirect him after the post back to a page that can check if is a real user or an attacker and stop him - but if is a real user must return back to his normal action.
Update 2
This all must be done in a general way, eg on BasePage, or on Global.asax or somewhere that is independed from the content of any page. Because we try to prevent a DoS attack, or multiple submit anywhere on any random place of any random page.
Yes I know how you can place a captcha on the contact page, but this is not what this question was first asked for - this questions asked how can carry post data to one different page, keep them there and then resend them back to the original one.
The obvious solution is to read all post back, and save them on the form, and then read them back and make on fly a form only with that data and make the post back. Here I am asking if there are any other better than this solution.
Other Applications
There is also the case that a user is inside a page that request authentication, but the authentication ticket has expired, and the user make post back. In this case we need to keep somewhere all the posted back data, to proceed with the login page, and resend them back to the first page that request the authentication.
Sure, just write the form data out to the captcha page in hidden elements with the additional captcha fields added to the form. Have your submit action post the whole thing back to the original. Using ASP.NET it's probably easier to have the captcha written to the same page with the form fields hidden, but you can do cross-page postbacks as I've described above.
Cross Page Posting might help you.
Why not implement the CAPTCHA with AJAX? Load the captcha object and form with Javascript in a div perhaps displayed lightbox style, accept the user input and post it to your server for validation, hence continue with the users post request or keep them there until they get it right (or cancel).
A more specific situation example:
Give the form submittal button an onClientClick value of some Javascript function. This function decides if this particular form needs a CAPTCHA. If it does it loads an interface for taking the CAPTCHA (which you'd need to do with some server-side code) and inserts the CAPTCHA's input element to the form that the user clicked to submit.
Once the user has entered the CAPTCHA input and clicks some button whose click event is bound to return to your first JS function, the Javascript intercepts this action and posts the full form, all the data from the original form and the CAPTCHA for validation. Your server script can now process all this at once!
This is the best solution I can think of that works similar to how you've asked, but I can't imagine why you want to perform the CAPTCHA on a different page.
Server.Transfer with MultiViews, Panels like control is fine with you? In this way, no need to bother about the Data Maintenance and Postbacks. You can do the validations in javascript.
You can keep both functionality in the same page to avoid moving data from one page to another page/Bring the data back to original page. You can utilize Session for this intermediate operation. Set it back to associated controls across Postback. You can create a class, Instantiate it and Initialize the control values in this class object. Save class object in Session. On Postback, You can reassign the values to the associated controls. This will definitely keep the things simple and without much complexity.
Doubts ?

How to: Cross-Site posting and redirection in ASP.NET webforms

Scenario:
The task I have at hand is to enable a single-signon solution between different organizations/websites. I start as an authenticated user on one organization's website, convert specific information into an Xml document, encrypt the document with triple des, and send that over as a post variable to the second organizations login page.
Question:
Once I have my xml data packaged, how do I programmatically perform a post to the second website and have the user's browser redirected to the second website as well.
This should behave just like having a form like:
action="http://www.www.com/posthere" method="post"
... and having a hidden text field like:
input type="hidden" value="my encrypted xml"
This is being written in asp.net 2.0 webforms.
--
Edit: Nic asks why the html form I describe above will not work. Answer: I have no control over either site; I am building the "middle man" that makes all of this happen. Site 1 is forwarding a user to the page that I am making, I have to build the XML, and then forward it to site 2. Site 1 does not want the user to know about my site, the redirect should be transparent.
The process I have described above is what both parties (site A and site B) mandate.
Send back a document that contains the from with hidden input and include an onload handler that posts the form immediately to the other site. Using jquery's document.ready() solves the issue of whether the DOM is loaded before the post occurs, though there are other ways to do this without jquery. You might want to include some small message on the screen to the effect that the user will be redirected shortly and provide a link which also does the post
...headers left out...
<script type='text/javascript'>
$(document).ready( function() {
$('form:first').submit();
});
</script>
<body>
<form action='othersiteurl' method='POST'>
<input type='hidden' value='your-encrypted-xml" />
</form>
</body>
You are thinking about this too process oriented, it would take you a month of sundays to try and work out all the bugs and moving parts with what you suggest.
You are already doing a post to another server so you really don't need to do anything. The form you have is already perfect, and when the other server intercepts the request that is when it makes the decision to either allow to user in and continue in through the site, or redirect them back to their Referer (sic) in the header. When redirecting back to the Referer they may want to tack on a message that says what was wrong, such as ?error=no_auth
I wrote on this for another question a while back. Hope this helps:
How do you pass an authenticaticated session between app domains

Resources