Day49 of learning python -- 跨站伪造请求CSRF

一、跨站请求伪造简介

  django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

  因此在提交服务器请求时,中间件需要客户端验证是否带有一个csrf字符串,通过该字符串来判断请求是否合法的,服务器才会做下一步操作。

全局:

  在Django框架下,默认是启动中间件的:django.middleware.csrf.CsrfViewMiddleware

局部:

  1)@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

在setting下,注释中间件
在views.py视图函数下
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def csrf1(request):
    if request.method == 'GET':
        return render(request,'csrf1.html')
    else:
        return HttpResponse('ok')

  2)@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

在setting下,使用中间件
在views.py文件下
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def csrf1(request):
    if request.method == 'GET':
        return render(request,'csrf1.html')
    else:
        return HttpResponse('ok')

 二、应用

  在启动防跨站请求伪造功能时,由于需要客户端带一个csrf字符串。而这个字符时,客户端首次登陆服务器时,会下发的,通过{% csrf_token %}得到

1)对于普通表单

由于普通表单在提交POST请求时,如果设置了{% csrf_token %},会有"submit"提交上去,urls.py:re_path('^csrf1.html$',views.csrf1)

views.py
def csrf1(request):
    if request.method == 'GET':
        return render(request,'csrf1.html')
    else:
        return HttpResponse('ok')
csrf1.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>csrf1</title>
</head>
<body>
<form action="/csrf1.html" method="post">
    {% csrf_token %}
   <input id="user" type="text" name="user">
    <input type="submit" value="提交">
</form>
</body>
</html>

2)Ajax

对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,一个是通过html提交csrf_token,另一个方式是通过cookie来提交到服务端。

方式一

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>csrf1</title>
</head>
<body>
{% csrf_token %} /*必须要的,因为这是服务器产生的csrf字符串,并下发给客户端的*/
<a onclick="Do();">AJAX提交</a>
<script src="/static/jQuery-3.3.1.js"></script>
<script>
 function Do() {
        var user = $('#user').val();
        var csrf1 = $('input[name="csrfmiddlewaretoken"]').val();
        $.ajax({
            url:"/csrf1.html",
            type:'POST',
            data:{'user':user,'csrfmiddlewaretoken':csrf1},
            success:function (arg) {
                console.log(arg);
            }
        });
    }
</script>
</body>
</html>

方式二、要导入jquery.cookie.js文件,这个文件是用来处理cookie字符串的,用来分割,可以查document.cookie:"csrftoken=049rQhDWuAiYCEMHQx8r6pgVoqQyAQZpxY2BySmIqvrhinLaqjiRfGPP13eMeGd9"

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>csrf1</title>
</head>
<body>
{% csrf_token %} 
<a onclick="Do();">AJAX提交</a>
<script src="/static/jQuery-3.3.1.js"></script>
<script>
    function Do() {
        var token = $.cookie('csrftoken');
        var user =  $('#user').val();
         $.ajax({
            url:"/csrf1.html",
            type:'POST', 
             headers:{'X-CSRFToken':token},   /*要放在请头中提交*/
            data:{'user':user},
            success:function (arg) {
                console.log(arg);
                alert('提交成功')
            }
        });
    }
</script>
</body>
</html>
posted on 2019-02-22 11:27  smile大豆芽  阅读(168)  评论(0)    收藏  举报