簡體   English   中英

檢查 django 表單有效性和 javascript

[英]Check django form validity and 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 和數據有效性是兩個不同的主題。

首先,您可以通過在請求頭check this 中發送 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'})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM