Django 如何验证 POST 参数

Django how to validate POST Parameters

我通过 POST 请求将一些参数传递给 django。我如何验证参数是否为整数、字符串以及内部是否没有代码注入等不安全的东西? 有我可以使用的 django 函数吗?

例如:

if request.method == 'POST':
    print request.POST.get('user_comment')

如何检查 POST 参数是否包含对我的系统没有危险的字符串?像

request.POST.get('user_comment').is_valid()

谢谢。

最简单的方法是创建一个表单:

from django import forms

class SingleForm(forms.Form):
    user_comment = forms.CharField(max_length=100)

然后

comment = SingleForm(request.POST or None)
if comment.is_valid():
    # here everything is cleaned and safe

或者您想不使用表格?

要检查 POST 数据是否安全、类型是否正确等,您可以使用 django 中的表单。例如,如果您需要 3 个必需参数,一个字符串和 2 个整数,您可以创建表单:

from django import forms

class MyValidationForm(forms.Form):
    first = forms.CharField()
    second = forms.IntegerField()
    third = forms.IntegerField()

并在视图中使用它:

if request.method == 'POST':
    form = MyValidationForm(request.POST, request.FILES)
    if not form.is_valid():
        # print some error here
    else:
        # do whatever you like

对于不包含危险内容的字符串进行过滤,没有通用的解决方案。数据库、XSS 等有不同的威胁,因此无法全部过滤。

关于代码注入,您可以使用bleach来净化用户输入:

>>> import bleach
>>> bleach.clean('an <script>evil()</script> example')
u'an &lt;script&gt;evil()&lt;/script&gt; example'

您可以在官方 Django 文档中找到有关安全性的更多信息:

如果您使用的是 Django REST Framework,那么您可以在视图中执行以下操作。

from rest_framework import status
from rest_framework.views import APIView

class MyView(APIView):
  def post(self , request):
    serializer = MySerializer(data = request.data)
    if serializer.is_valid():
      serializer.save()
      return Response({"status" : "Success"} , status = status.HTTP_201_CREATED)

如果您不使用 DRF,请查看 serializers.py to see how is_valid() is implemented. Basically, it calls run_validators() function of django.db.models.fields。希望这对您有所帮助!

您可以考虑在字段前使用 cleaned_ 对其进行验证。 例如,如果你想检查用户名,并且你有一个为它定义的模型,

class MyModel(models.Model):
    username = model.CharField(max_length = 255)

然后同样你有一个类似下面的表格

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['username']

    def clean_username(self):
        username = self.cleaned_data.get('username')
        """ this will give you the actual username from the field
            Now you may get that validated
        """
        if username == "blah blah":
            return forms.ValidationError("This isnt any name!")
        else:
            return username

这是根据 django 文档说的:

"Field 子类上的 clean() 方法负责 运行 to_python()、validate() 和 run_validators() 的正确顺序并传播它们错误。如果在任何时候,任何方法引发 ValidationError,验证将停止并引发该错误。此方法 returns 干净的数据,然后将其插入到表单的 cleaned_data 字典中.

在表单子类上调用了 clean_() 方法——其中替换为表单字段属性的名称。此方法执行特定于该特定属性的任何清理,与其所属的字段类型无关。此方法不传递任何参数。您将需要查找 self.cleaned_data 中字段的值,并记住此时它将是一个 Python 对象,而不是表单中提交的原始字符串(它将在 cleaned_data因为通用字段的clean()方法,上面已经清理过一次数据了)。"