检查 django 表单有效性和 javascript



我正在使用一个 django 模型表单,我想保护我免受恶意用户输入(不仅仅是错误的输入(的侵害。

据我了解,django 表单足够安全:.is_valid()检查用户输入,csfr防止跨站点伪造。

但是这次我的表单不是使用action='/path/to/my/view'来调用 django 视图,而是我的提交按钮调用 javascript 函数,该函数获取数据并使用 ajax 调用 django 视图来访问数据库,然后在屏幕上显示结果。

所以我认为不再受到保护(.is_valid()不被调用,csfr不发送(。我说的对?如果是这样,我该怎么办?

我认为:

1(这不是问题,表格是合理的安全(为什么?

2(重构代码并使用django视图

3(django表单验证都不够安全,所以无论如何我应该做更多的事情(什么?

4(我的javascript函数正在使用ajax将数据发送到django视图。我应该使用该数据来实例化绑定表单并对此使用.is_valid(),但无论如何我没有使用 csfr,对吧?

5(使用html验证器(对我来说,它们看起来不适应检查恶意输入数据(

6( 其他?

一些代码,要完整,但很可能你不需要它

我的forms.py

class NameListForm(forms.ModelForm):
class Meta:
model = Name
fields = ['namelanguage', 'nametype', 'gender']
widgets = {
'gender': forms.CheckboxSelectMultiple(),
}

我的models.py

class Name(models.Model):
name = models.CharField(_('nome'), max_length=50, default='')
namelanguage = models.ForeignKey(
NameLanguage, related_name='%(app_label)s_%(class)s_language',
verbose_name=_('linguaggio'), on_delete=models.PROTECT)
nametype = models.ForeignKey(
NameType, related_name='%(app_label)s_%(class)s_tipo',
verbose_name=_('tipo'), on_delete=models.PROTECT)
gender = models.ForeignKey(
Gender, related_name='%(app_label)s_%(class)s_gender',
verbose_name=_('sesso'), on_delete=models.PROTECT,
blank=True, null=True)

我的template.html

<form action="" method="post">
<div>
<div class="col-md-auto">
{{ name_list_form.namelanguage.label_tag }}<br />
{{ name_list_form.namelanguage }}
{{ name_list_form.namelanguage.errors }}
</div>
<div class="col-md-auto">
{{ name_list_form.nametype.label_tag }}<br />
{{ name_list_form.nametype }}
{{ name_list_form.nametype.errors }}
</div>
<div class="col-md-auto">
{{ name_list_form.gender.label_tag }}<br />
{{ name_list_form.gender }}<br />
{{ name_list_form.gender.errors }}
</div>
</div>
{{ name_list_form.non_field_errors }}
<div>
<button class="btn btn-primary" id='list_name' type="button" onclick="FilterBy()">{% trans "List Names" %}</button>
<button class="btn btn-primary" type="button" onclick="RandomNames()">{% trans "Random Names" %}</button>
</div>
{% csrf_token %}
</form>

我的javascript.js

function FilterBy() {
var language_id = document.getElementById("id_namelanguage").value;
var nametype_id = document.getElementById("id_nametype").value;
...
$.ajax({type: 'POST',
url: '/lists/get-list-name/',
data: {
language: language_id,
nametype: nametype_id,
...
},
success: function (lista) {
if (lista.result === 'OK') {
//do something
};
}
});
};

我的views.py

def GetListName(request):
if request.is_ajax():
language = request.POST.get('language')
nametype = request.POST.get('nametype')
# it makes sense to check validity here? and anyway I'm not using csfr, right?
# name_list_form = NameListForm({'namelanguage': language, 'nametype': nametype, etc})
# if name_list_form.is_valid():
...
return JsonResponse({'result': 'OK', 'data': my_dict})

CSRF 和数据有效性是两个不同的主题。

首先,您可以通过在请求标头中发送 CSRF 令牌来检查 CSRF 错误。

其次,您可以在JS中以与经典形式相同的方式发送数据。

// JS, don't forget to add your CSRF headers
$.ajax({
method: "post",
url: "...",
data: {
namelanguage: "foo",
nametype: "bar",
gender: "baz",
});

只需像您一样处理您的表单即可。如果您不想确定表单是从 JS 脚本提交的,您可以抛出异常,但这并不能保证它真的如此。任何人都可以修改客户端标头以使您这样认为。

# python
from django.http.response import HttpResponseBadRequest, HttpResponseNotAllowed
def GetListName(request):
if not request.is_ajax():
return HttpResponseNotAllowed()
form = NameListForm(data=request.POST)
if not form.is_valid():
return HttpResponseBadRequest()
# do stuff with your form
return JsonResponse({'result': 'OK', 'data': 'some data'})

相关内容

  • 没有找到相关文章

最新更新