初谈dango的post提交csrf设置和文件上传

Posted wuzhibinsuib

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初谈dango的post提交csrf设置和文件上传相关的知识,希望对你有一定的参考价值。

在django中配置了中间件CsrfViewMiddleWare,每次post请求都post请求的话,都需要在form表单中加入{{ csrf_token }},它的运行原理是

在form表单中生成一个隐藏的input标签

技术图片

 

 在post的请求头中把csrftoken加入cookie中

技术图片

 

 从上图可以看出来,两个键值对都不相同,验证的原理是:

技术图片

 

cookie是保存在浏览器本地的获取之后时是不会变化的,而隐藏在form表单中的csrfmiddlewaretoken是每次请求都会发生变化的,但是在server端解出来的secret是一致的就表示csrf验证通过。

post请求使用form表单提交数据比较简单只需要在form中加入{% csrf_token %},POST请求使用Ajax提交时使用 以下的方法

方法1:

  通过获取隐藏的input标签中的csrfmiddlewaretoken值放在data发送。

技术图片
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse

def index(request):
    if request.method == GET:
        return render(request,login.html)
    else:
        csrf = request.POST.get(csrfmiddlewaretoken)
        return HttpResponse(csrf)
views.py
技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form method="post" action="/login/">
        <!--必须加上这个应该这个还有Ajax的值是从这个获取的,并且POST的cookie携带csrftoken也是这个的作用-->
        {% csrf_token %}
        <input id="id_username" type="text" name="username">
        <input id="id_password" type="password" name="password">
        <input id="id_button" type="button" value="button">
    </form>
<script src="/static/jquery-2.1.4.min.js"></script>
<script>
    $("#id_button").click(function () {
        $.ajax({
        url:/login/,
        data:{csrfmiddlewaretoken:$("[name=‘csrfmiddlewaretoken‘]").val()},
        type:"POST",
        success:function (arg) {
            alert(arg);
        }
    })
    })

</script>
</body>
</html>
login.html

注意form标签中的{% csrf_token %}不能删除。

方法2:

  在Ajaxsetup配置提交,只需在AjaxSetup中配置

 $.ajaxSetup({
        data: {csrfmiddlewaretoken: {{ csrf_token }}},
    });
技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post" action="/login/">
    <!--必须加上这个应该这个还有Ajax的值是从这个获取的,并且POST的cookie携带csrftoken也是这个的作用-->
    {% csrf_token %}
    <input id="id_username" type="text" name="username">
    <input id="id_password" type="password" name="password">
    <input id="id_button" type="button" value="button">
</form>
<script src="/static/jquery-2.1.4.min.js"></script>
<script>
    // 第二种方式
    $.ajaxSetup({
        data: {csrfmiddlewaretoken: {{ csrf_token }}},
    });
    $("#id_button").click(function () {
        $.ajax({
            url: /login/,
            // data:{csrfmiddlewaretoken:$("[name=‘csrfmiddlewaretoken‘]").val()},
            type: "POST",
            success: function (arg) {
                alert(arg);
            }
        })
    })

</script>
</body>
</html>
login.html

方式3:

  前端也能操作后端返回的cookies,所获取响应头中的cookies中csrftoken字段的值放在响应头中,操作cookies需要引入jquery.cookie.js插件

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post" action="/login/">
    <input id="id_username" type="text" name="username">
    <input id="id_password" type="password" name="password">
    <input id="id_button" type="button" value="button">
</form>
<script src="/static/jquery-2.1.4.min.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>

    $("#id_button").click(function () {
        $.ajax({
            url: /login/,
            // data:{csrfmiddlewaretoken:$("[name=‘csrfmiddlewaretoken‘]").val()},
            type: "POST",
            // 第三种方式在请求头中,这个直接从响应的中获取cookie所以不需要设置{% csrf_token %}
            headers: {"X-CSRFToken": $.cookie(csrftoken)},
            success: function (arg) {
                alert(arg);
            }
        })
    })

</script>
</body>
</html>
login.html

这个是通过响应中的cookies获取csrftoken字段的值提交的,所以不需要{% csrf_token %}配置

注意在请求头中为键为“X-CSRFToken”

每个Ajax请求都要设置头不方便,可以设置一个通用头信息,就可以不用每次都在Ajax请求的头里面配置了

技术图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post" action="/login/">
    {% csrf_token %}
    <input id="id_username" type="text" name="username">
    <input id="id_password" type="password" name="password">
    <input id="id_button" type="button" value="button">
</form>
<script src="/static/jquery-2.1.4.min.js"></script>
<script src="/static/jquery.cookie.js"></script>
<script>
    var csrftoken = $.cookie(csrftoken);
    function csrfSafeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $.ajaxSetup({
        beforeSend: function (xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        }
    });
    $("#id_button").click(function () {
        $.ajax({
            url: /login/,
            type: "POST",
            success: function (arg) {
                alert(arg);
            }
        })
    })
</script>
</body>
</html>
login.html

注意,这里如果不配置{% csrf_token %}响应头里面不会有set-cookie,发送post的请求里面也就没有csrftoken的值,但是方式三种且不需要配置{% csrf_token %}不知道是什么原因 。

 

以上是关于初谈dango的post提交csrf设置和文件上传的主要内容,如果未能解决你的问题,请参考以下文章

Django 文件上传

django 页面进行ajax post提交时,页面要添加{% csrf_token %}

django 页面进行ajax post提交时,页面要添加{% csrf_token %}

django 页面进行ajax post提交时,页面要添加{% csrf_token %}

yii2 ajax post设置csrf

django1.11如何用post方法提交表单