美文网首页
(13)Django - CSRF防护

(13)Django - CSRF防护

作者: libdream | 来源:发表于2019-03-14 13:10 被阅读0次

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

#user.html 部分代码
<form class="form" action="" method="post">
            {% csrf_token %}
            <div>用户名:<input type="text" name='username'></div>
            <div>密 码:<input type="password" name='password'></div>
            {% if new_password %}
                <div>新密码:<input type="password" name='new_password'></div>
            {% endif %}
            <button type="submit" class="btn btn-primary btn-block">确定</button>
</form>

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


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的信息,否则服务器会视该请求是恶意请求。代码如下:

<script>
    function submitForm(){
        var csrf = $('input[name="csrfmiddlewaretoken"]').val();
        var user = $('#user').val();
        var password = $('#password').val();
        $.ajax({
            url:'/csrf1.html',
            type:'POST',
            data:{'user':user,
                'password':password,
                'csrfmiddlewaretoekn':csrf},
            success:function(arg){
                console.log(arg);
            }
        })
}
</script>

相关文章

网友评论

      本文标题:(13)Django - CSRF防护

      本文链接:https://www.haomeiwen.com/subject/lpsqmqtx.html