(13)Django - CSRF防护

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种对网站的恶意利用,窃取网站的用户信息来制造恶意请求。
Django为了防护这类攻击,在用户提交表单时,表单会自动加入csrftoken的隐含值,这个隐含值会与网站后台保存的csrftoken进行匹配。只有匹配成功,网站才会处理表单数据。这种防护机制称为CSRF防护。
在Django中使用CSRF防护功能,首先在配置文件settings.py中设置防护功能的配置信息,在配置文件的中间件实现,默认已开启。
CSRF防护只作用于POST请求,并不防护GET请求,因为GET请求以只读形式访问网站资源,并不破坏i和篡改网站数据。以mysite为例,在模板user.html的表单

标签中加入内置标签 csrf_token 即可实现CSRF防护,代码如下:

#user.html 部分代码

            {% csrf_token %}
            
用户名:
密 码:
{% if new_password %}
新密码:
{% endif %}

启动运行mysite项目,在浏览器打开用户登录界面,查看页面源码可以发现表单的隐藏域,隐藏域由模板语法{% csrf_token %}所生成的,网站生成的 csrftoken 都会记录在隐藏域的 value 属性中。当用户每次提交表单时, csrftoken都会随之变化。


(13)Django - CSRF防护_第1张图片
image.png

如果想要取消表单的 CSRF 防护,可以在模板上删除{% csrf_token %},并且在相应的视图函数中添加装饰器@csrf_exempt,代码如下:

from django.views.decorators.csrf import csrf_exempt
#取消CSRF防护
@csrf_exempt
def loginView(request):
    pass
    return render(request, 'user.html', locals())

如果只是在模板上删除{% csrf_token %},没有在相应的视图函数中设置过滤器@csrf_exempt,那么当用户提交表单时,程序会因CSRF验证失败而抛出403异常的页面。


如果在配置文件settings.py中删除中间件CsrfViewMiddleware,这样就使整个网站都取消CSRF防护。在全站没有 CSRF防护的情况下,又想对某些请求设置CSRF防护,那么在模板上添加模板语法{% csrf_token %},然后再相应的视图函数中添加装饰器@csrf_protect即可实现。

from django.views.decorators.csrf import csrf_protect
#添加CSRF防护
@csrf_protect
def loginView(request):
    pass
    return render(request, 'user.html', locals())

需要注意的是,在日常开发中,如果网页某些数据是使用前端的Ajax实现表单提交的,那么Ajax向服务器发送POST请求时,请求参数必须添加csrftoken的信息,否则服务器会视该请求是恶意请求。代码如下:


你可能感兴趣的:((13)Django - CSRF防护)