CF Muse Reader Asks:
You suggest both client and server side should be used for validation. Just to check - I should code so that js picks up the errors first using event code or onsubmit then let server side pick up the errors on submit using cfinput validate/required etc. Or do I recode all the stuff to be event driven such as onchange etc.
This question refers to the previous post on form validation. From the way the question is phrased I believe the reader is probably proficient at JavaScript. There are some amazing things you can do with JavaScript, and I'm in favor of creating intuitive interfaces that help your user cope with the complexity of your application. Obviously JavaScript is or can be a big part of that solution. If your concern is to provide a better user experience then JavaScript is helpful and necessary. If your concern is to validate your data for accuracy and security then you must use server side code to check your form inputs.
As an example, you might have a form like this:
The point is, that regardless of what you do on the client you should validate the inputs on the server. On a public form you have little or no control over what is happening on the client. All you can really control is what goes into you application or database.
Now, the second part of the question asks about "cfinput" and "validate/required". To be clear, when you use CFFORM you are not creating server side code. You are, in fact creating complex JavaScript routines for validation that function on the client side - so you are not using server side validation. On a side note, I really detest cfform and tend to avoid it in favor or custom JS or something like Dan Switzer's "Qforms". Unless I'm using flash forms I avoid cfform altogether. One additional approach provided by Coldfusion that some folks use is the "hidden variable" approach. The muse reader above may be referring to this idea. It's actually a rudimentary method for server side validation. Here's how it works. You would alter your form as follows:
Cleverly, Coldfusion looks for the "_required" or "_date" (or _integer or _float etc. - see the docs) that matches the name of a form element and then validates that element on the server - displaying the message you have chosen to the user and asking them to go back and fix the problem. Yes, this is server side validation because the server is doing the checking, but is it secure from malicious attack? Nope. All a nere-do-well has to do is remove the "myDateOfBirth_date" form element from his custom form or CFHTTP call. The server's validation is based on these inputs being present. If those form elements are not part of the request, the server will not check them.
Server side validation is the process of painstakingly checking the inputs and making sure they contain what they are supposed to contain. Most of my server side validation code looks like this:
In my opinion, if security and data integrity are your primary concerns, you should start with server side validation and put it above client side validation in importance. You should add client side validation to reduce round trips to the server and maximize the user experience but don't rely on it to keep your site safe or your data sound.
Client-side validation basically just improves the UI for the user. I'm a strong advocate of client-side validation, but I've also seen people spend to much time trying to bullet proof their client-side validation while ignoring server-side validation.
Client-side validation should be designed to catch user mistakes and notify them of the mistakes quickly. Server-side validation ensures that the values receive constrain to your business logic rules and that they don't break your code.
It's like the story of the fireman, who has pants and suspenders, sure the suspenders are nice, but if they fall and you have no belt, how will you hold your pants up?
So use client validation, it's great as a first step for validation..But have the server side just in case, especially if you use it within queries or any other highly sensitive to hackers.
<cfqueryparam
<cfparam
all ways to specify datatype's for incoming variables.
Even if your not using it in a query, what if the data isn't the datatype you expect and they had javascript off?
cfif isdefined(form.my_variable)
sure the above prevents if the variable does not exist
but what if you need a numeric value and you get a string garbage as well.
Good post, mark.
Remeber too that a cfc that is enabled for remoting (meaning access="remote") is capable of receiving web service calls as well as AMA calls.... so armed with the URL you would be able to generate the WSDL, create a stub/proxy class and utilize it as a web service.
That sounds like a lot of work, but even novice developers armed with user friendly development tools that abstract the process of unpacking the XML could probably make short work of it.
Yes it IS more work than simple HTML forms, and hence "more secure" because it's "more difficult" in the same way that a $500 pound home safe is "more secure" than a $100 dollar home safe. Both, however, are still Home safes - and they don't do much good if the thief can simply abscond with them and pick them at leisure.
My point is that no matter what you choose to do on the client (and all these ideas are marvelous) you still need server-side validation.
In fact, its been like this forever, and I'm sure people requested one of the many CF 'owner' companies to fix this and at the very least allow this stupid auto validation to be turned off. But why would the listen - some issues are best kept for the next 'owner of the platform' to deal with. It has caused me a great deal of headache as I"ve had to work around this many times.
(don't tell me to rename my fields as this is not always possible. A field titled "request" and one "request_date" are logical fields to be present in a database/form/app.)
I agree about the server side validation - and I don't know anyone who uses it. I would never used "canned" validation for anything important anyway. I made that very point above.
As for "turning it off" so you can use your pet naming convention... why would you NOT be able to rename a form field? My only conclusion is that you are using "cfupdate" or "cfinsert" to get your data into your database. that is also a bad idea. Write SQL insert statements instead. Cfupdate is too restrictive and gives you very little feedback on what's going on under the covers. And you can't leverage SQL either - as in a combined insert/update statement.
That's my take - so I agree with you half way ... is that good enough for us to remain friends? :)
If you assume I'd use a useless tag like cfinsert/cfupdate then we won't BE able to be friends in the first place ;o)
The application i'm working on is most likely the largest CF application in the history of this (silly) platform. I can't disclose the details though I can say it is used by many government authorities in the UK and by that definition - that makes it huge in the sense of the biz logic and strictness it uses. It's bolted on an old (over 10 years) oracle db whose columns cannot be changed.
The app is built on a framework I created which kinda resembles hibernate but on steroids. Think 'automatic gui generation with total db persistency'. The amount of forms this app generates is HUGE. Renaming db fields is out of the question. The framework is solid, and runs many apps within it as modules. Infact, I wish I could release it somehow (I can't obviously).
We worked around that problem though the very existence of this kind of silly issue adds additional nails to the coffin of CF.
I can't help but wonder - if the next CF owner is Microsoft - would it be renamed ColdFusion MS?
(i was kidding of course - we can remain friends - just don't mention cfinsert/update ever again ;o)