Django 表单的 CSRF 保护
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 攻击。
相关文章