Django跨站请求伪造

一、简介

django为用户实现防止跨站请求伪造的功能,通过中间件django.middleware.csrf.CsrfViewMiddleware 来完成。

当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错

1.客户端在非Django返回页面上发送post请求时,会被Django拦截,但非服务器报错

2.客户端在Django返回页面上发送post请求时,需要加上{% csrf_token %}方能发送成功
因为在之前访问服务器后,服务器发送一段字符串

第二次post请求访问需要加上{% csrf_token %}带着这个字符串认证

除此之外,还有另一种cookie认证方式,后面有讲到。

而对于django中设置防跨站请求伪造功能有分为全局和局部。

全局:

中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

二,简单原理(个人见解,欢迎指正)

每个Django服务端settings.py源码里都有一个:

SECRET_KEY = '^!9td%%@mim%&xhfirgwivgxk!qt3dwg6vo=m*@37nkzw5uspk'

这个就是密匙,用来进行验证

首先第一次访问服务器,服务器会把密匙发给客户端(当然客户端是看不见的),客户端拿到密匙,拼接上当前客户端时间,进行md5(也可能其他的)加密,然后把这个加密信息和之前的当前客户端时间发到后台之后,后台拿到客户端当前时间和密匙也进行MD5加密,然后比较两次结果,一样则认为没有问题

所以要通过验证需要两点:

1.拿到密匙

2.根据规则加密(自动的)

3.发过去MD5加密结果(时间会自动发)

有的还加上了有效时间限制和有效时间内的次数限制(第二次相同的无效)

三、应用

1、普通表单

veiw中设置返回值:
  return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))  
     或者
     return render(request, 'xxx.html', data)
  
html中设置Token:
  {% csrf_token %}
#在页面自动加上一个隐藏的input标签,不依赖form表单而存在
#<input type="hidden" name="csrfmiddlewaretoken" value="Hx9OMDpLJFsG8P7Sy6gGGh5FGXmBXywQV5JQhDPmi7HFmsDh08GILYRPNEwvGouF">

2.Ajax

对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,使用如下方式。

第一种方式 :直接在hide标签中获取到data里并提交

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#<form action="/ajax/" method="post">#}
        {% csrf_token %}//不依赖form表单而存在
{#    <input type="submit">form提交#}
{#</form>#}
<script src="/static/jquery-3.3.1/jquery-3.3.1.js"></script>
<button id="q">提交</button>
<script>
    $("#q").click(function () {
        var csrf=$('input[name="csrfmiddlewaretoken"]').val();//拿到csrf的字符串
        $.ajax({
            url:"/ajax/",
            type:"POST",
            data:{"k1":"123","csrfmiddlewaretoken":csrf},
            //data:{"k1":"123","csrfmiddlewaretoken":{{csrf_token}},},不用获取
            success:function (arg) {
                console.log(arg)
            }
        })
    })
</script>

</body>
</html>

第二种方式 : 获取本地cookie相关信息,放在请求头中发送 两种方式,获取值不同
document.cookie 能获取到本地Cookie(字符串形式),如下:

“csrftoken=CibmiHzG0mFPA7EqubC0I6jqRCBJjvKbQQLoNHZhzOUOOKaPWd22NN5AYjLD2lI0”

<script src="/static/jquery-3.3.1/jquery-3.3.1.js"></script>
<script src="/static/carhartl-jquery-cookie-92b7715/jquery.cookie.js"></script>
<button id="q">提交</button>
<script>
$("#q").click(function () {//第二种方式
        var token = $.cookie('csrftoken');
        $.ajax({
            url:"/ajax/",
            type:"POST",
            headers:{"X-CSRFToken":token},
            data:{"k1":"123",},
            success:function (arg) {
                console.log(arg)
            }
        })
      })
</script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值