Django 表单的 CSRF 保护

2023-04-11 00:00:00 django 表单 保护

CSRF(Cross-Site Request Forgery)跨站点请求伪造攻击是一种常见的 WEB 攻击方式。攻击者可以构造一些恶意的链接或者通过一些方法,将被害人不知情地提交一些恶意请求,从而造成严重后果。 Django 为了防范此类攻击,默认启用了 CSRF 保护机制。

CSRF 保护需要借助 Django 的中间件“django.middleware.csrf.CsrfViewMiddleware”。在 Django 3.0 及以上版本中,此中间件默认启用,无需手动配置。在 Django 2.2 及以下版本中,需要在配置文件中添加以下配置:

MIDDLEWARE = [
    'django.middleware.csrf.CsrfViewMiddleware',
    # ...
]

当用户请求一个视图函数时,Django 会自动为其生成一个 CSRF token,并将其储存在用户 session 中。在渲染表单时,我们需要在表单中加入一个隐藏字段,来携带此 token。在提交表单时,Django 会拿用户提交的 token 与 session 中的 token 进行比对,以此来验证请求的合法性。若两者不一致,则会抛出“CSRF token missing or incorrect”异常。

接下来我们来演示如何使用 Django 表单的 CSRF 保护:

# forms.py
from django import forms

class CommentForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField(max_length=100)
    content = forms.CharField(widget=forms.Textarea)

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(CommentForm, self).__init__(*args, **kwargs)

    def clean(self):
        cleaned_data = super().clean()
        if self.request:
            cleaned_data['csrfmiddlewaretoken'] = self.request.POST.get('csrfmiddlewaretoken')
        return cleaned_data

# views.py
from django.shortcuts import render
from .forms import CommentForm

def post_detail(request):
    if request.method == 'POST':
        form = CommentForm(request.POST, request=request)
        if form.is_valid():
            # 处理表单数据
            return render(request, 'success.html')
    else:
        form = CommentForm(request=request)
    return render(request, 'post_detail.html', {'form': form})

# post_detail.html
<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">提交</button>
</form>

在上述代码中,我们定义了一个“CommentForm”表单类,并在 init() 方法中将 request 对象传递进去。在 clean() 方法中,我们手动将得到的“csrfmiddlewaretoken”添加到 cleaned_data 中。在视图函数中,我们通过“request=request”将 request 对象传递给表单类。

在“post_detail.html”模板文件中,我们使用 Django 的内置标签“{% csrf_token %}”生成隐藏的 CSRF token 字段,并在表单中添加该字段。提交表单后,Django 会自动验证 CSRF token 的合法性。

以上就是使用 Django 表单的 CSRF 保护的详细示例,我们可以通过以上方法,有效地防范 CSRF 攻击。

相关文章