I have a form which allows a user to create an unlimited number of fields. If this forms fails validation I want the user to return to this page with the form populated with their previous input values - i.e. I want these fields to persist.
With a normal form I could do this with {{ old 'title' }}, however, these additional fields are being generated through JavaScript and so I cannot add this PHP snippet. What is the best way for me to retrieve these previous input values?
3 ways to do this, cache, sessions and cookies.
cache and sessions are server side which is much better for security, however it will take extra time and effort for setting up, but if the data is not sensible and can be passed within cookies, better to the cookies.
The best thing about cookies for your current situation is: you can set it up directly from your front end JS code.
Related
I have read a lot of answers relating to how to dynamically add forms to an model formset in Django and can successfully implement that. However, I would now like to submit the formset with AJAX. This is mostly working now but I have an issue that I can't find a solution to in any other answer:
If you dynamically add a form to the formset, you give it a new form id number that is one larger than the maximum the form currently has and you also increment the management TOTAL_FORMS count by one. The newly added form then saves successfully as a new object.
I am trying to submit by AJAX so the user can continue editing without having the page refresh. The formset saves fine but any dynamically added forms are now existing objects. To account for this I need to increment the INITIAL_FORMS count on the management form when the save is successful. Easy enough. However, I've also realised I need to give the newly created objects an ID since they now exist in the database.
How can I get my view to tell me the ID of the new objects in its response to the AJAX call? Or is there a better way of looking at this?
Django forms and formsets are intended for classic browser-based posting of data. Though they can definitely be made to work with Javascript, the more you want to part from the normal behavior, the more complex it gets.
Depending on your requirements, you might start thinking about dropping it and switch to Javascript + REST endpoint. Of course, if you need progressive enhancements and you are required to have it work without javascript, that's not an option.
In any case, you want to have a customized view for posting from JS, so that you can get the result back and parse it easily in your AJAX handler. Probably some JSON.
There are several approaches you could take.
Have your AJAX send data to a different URL. This is pertinent if you have an API or are planning to build one at some point. So your form, when submitted normally, will do its old-style processing but your AJAX will talk to the API endpoint instead.
For instance, your form send to https://example.com/myform, but your Javascript code talks to REST api at https://example.com/api/v1/mymodel/ (sending PUT, POST and DELETE requests as appropriate).
Or if you don't have an API and building one seems overkill, you may just alter your view so it formats its output differently depending on whether the data is being submitted in the regular way or using AJAX.
You'd go about it like this:
class MyFormView(.....):
def render_to_response(self, context, **kwargs):
if self.request.is_ajax():
return self.render_to_json(context, **kwargs)
return super().render_to_response(context, **kwargs)
def render_to_json(context, **kwargs):
data = {
# see below!
}
return HttpResponse(
content=json.dumps(data).encode('ascii'),
content_type='application/json',
)
This is just an outline. You need to ensure is_ajax will detect it properly (see django doc). And you need to properly build data from context: extract the things you want to send back to your JS code and put them in the dict.
You will find it's manageable if you just do this for one, maybe two views in your project, but very quickly you'll want to have a small API instead, especially given how easy it is to build one with packages such as Django REST framework.
In your view, where you save the object, AFTER the save, the object.id will contain the new id for the object, which you can return via json or however you want in your ajax response, and then yes you will need to fill that into the formset row so that it will be submitted the next time.
One thing you have to watch out for is that django expects all existing rows to be at the top of the formset, and any new rows to be at the bottom. Otherwise, the formset save will complain about missing id's. So if you're doing any kind of sorting in your javascript, you can't do that.. unless you do quite a bit of fixing of all the field names etc in the formset. The formset code uses the numbers in the management form to determine which rows to insert and which rows to update, it does not do it on the basis of whether or not an id is present. Unfortunately...
i was reading about AntiForgeryToken but do not understand the actual use or importance. i saw people wrote a code like in their form as
#using (Html.BeginForm("Create", "Register"))
{
#Html.AntiForgeryToken()
}
so what it does....it will generate a unique token and when form will post then this unique toke will pass and as well as a cookie will pass with same unique token value and two unique data will compare at server end that both are equal or not. if not then some tamper occur.
i just do not understand if other form field value change or tamper then how that tampering can be determine. suppose we often store valuable data inside hidden fields. if i need to secure that hidden fields value then how AntiForgeryToken can help us?
can we use AntiForgeryToken to wrap up those valuable data inside it and later compare at server end.
can anyone give me bit of sample code by which i can put 3 valuable data in my page and if tamper then a friendly message will be show to user. guide me how to do it. thanks
The idea behind the AntiForgeryToken is to prevent data being posted from a "fake" source. An attacker using a fake (forged) form can trick the user to submit any kind of data using their current session context. As you can imagine this can do quite a lot of damage.
A way to prevent this is to have a hidden field on your forms containing user specific data(something random) that is stored in the session, so that the bad guys can't forge it. In this case when a user posts the data, but doesn't have the user specific token, you can treat is as being malicious.
I think you have a misconception that the anti forgery token is about detecting whether the data posted has been "tempered" with, which it is not.
Here is more on this.
I'm implementing a 3D CAPTCHA for my website.
My original idea was to store the expected captcha solution in a session variable. After a user submits a form, I'd compare it with their response.
What happens if the user opens my website in multiple tabs though? For each tab a new CAPTCHA challenge is generated and the expected response variable in the session is overwritten.
Now consider the user submits a form in an "old" tab. Since the expected response variable in the session has been overwritten, they won't pass the test.
Should I worry about this? How would you deal with it?
That is the general approach for captchas and sometimes a reason why they do not validate.
This is a goood read http://www.sitepoint.com/captcha-inaccessible-to-everyone/ why not to use captcha
You could however add them in an array instead and see if the answer exists in array.
You are not stating which language you are using otherwise i could provide some code.
I am currently using the CodeIgniter framework, and looking to strengthen the XSS protection by using HTMLPurifier (http://htmlpurifier.org/).
Is my understanding correct that you want to 'clean' data on post, so that its purified before its inserted into the Database? Or do I run it before displaying in the view?
If so, do I want to run HTMLPurifier on every single post that takes place? Since the app contains a lot of forms, I'd hate to have to selectively choose what gets cleaned and what doesnt - assuming that I can intercept all posts, is this the way to go? Of course, I validate some fields anyway (like email addresses, numeric numbers, etc)
Use $this->input->post() to get $_POST data. Codeigniter filters it automatically if global xss filter is set to true.
See the docs: http://codeigniter.com/user_guide/libraries/input.html
Edit: to clarify
Yes you should filter before inserting into the DB and yes you should filter all user input.
A quick google search, http://www.google.com/search?q=codeigniter+htmlpurifier, led to this page: http://codeigniter.com/wiki/htmlpurifier which is a helper for htmlpurifier. Regarding catching all $_POST data: you have to do something with the data, right? In your models, when you're doing that something, just make purify() part of that process:
$postdata = purify($_POST);
In order to use some AJAX calls, we use often some input type="hidden". But these values can be easily changed. So, is it a builtin rails feature than permit to send date to AJAX, withouth being usable by user, or than can't be changed by user ?
In my current rails apps, i'm using filters for discard all malicious actions on my controllers. I am not building a public API, so i don't really need more powerful checks.
But for examples, i have an apotomo widget displaying some data, using some input hidden. But if you change it, you can access to another data set. In my case, it's not really an issue, cause all these users have the right to access these data sets anyway.
But is it some manner to give datas to ajax call, in a secure way ? Or the only security, is about rights management ?
All input that comes from the user is insecure as you do not have control over it! Users even do not need a webbrowser but can use some other program (like curl or wget) to send manipulated data.
As you state, using a whitelist (not a blacklist as you can never be sure of all bad, but of all good!) is a good way to start.
To make sure the hidden fields have not been changed you can use some kind of checksum that is calculated on server side using a fixed secret. This secret must never be exposed to your visitors!
hash = md5(field_1 + field_2 + field_3 + my_secret)
When these four hidden fields (field_1..3, hash) arrive in your form you can recalculate the hash and compare it with the params[:hash] in order to be sure the field_1 to field_3 have not been changed.