154.Ajax处理csrf防御

在普通的form表单中采用post请求提交数据,可以在form表单的method=post的form标签下面,添加一个csrf_token标签{% csrf_token %},或者是直接手动的添加一个input标签,<input type='text' name='csrfmiddlewaretoken value='{{ csrf_token }}'>,都可以在form表单中做好csrf防御的工作。但是如果我们的数据是通过jQuery,Ajax提交的,那我们就不能使用csrf_token标签来处理csrf攻击了。这种情况下,可以在form表单中添加csrfmiddlewaretoken,或者是通过ajax在我们的请求头中设置一个X-CSRFToken变量,我们可以从返回的cookie中提取csrf_token,再设置进去。在我们的项目中创建一个js文件为:myajax_csrf.js,用来定义获取cookie中的csrftoken的函数,示例代码如下:
function getcookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(";");
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

var myajax_csrf = {
    'get': function (args) {
        args['method'] = 'get';
        this.ajax(args);
    },
    'post': function (args) {
        args['method'] = 'post';
        this._ajaxSetup();
        this.ajax(args);
    },
    'ajax': function (args) {
        $.ajax(args);
    },
    '_ajaxSetup': function () {
        $.ajaxSetup({
            beforeSend: function (xhr, settings) {
                if (!/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", getcookie('csrftoken'));
                }
            }
        });
    }
};
在我们的转账html中加载js文件,示例代码如下:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ICBC</title>
    <!--加载js文件-->
    <script src="{% static 'myajax_csrf.js' %}"></script>
    <script>
        $(function () {
            $("#submit").click(function (event) {
               <!--阻止form表单采用post请求提交的方式-->
                event.preventDefault();
                var email = $("input[name='email']").val();
                var money = $("input[name='money]").val();
                
                <!--采用post请求的方式提交-->
                myajax_csrf.post({
                    'url': '/transfer/',
                    'data': {
                        'email': email,
                        'money': money,
                    },
                    'success': function (data) {
                    // 如果状态等于200 才会走到success的回调中
                        console.log(data);
                    },
                    'fail': function (error) {
                        console.log(error);
                    }
                });
            });
        });
    </script>
</head>
<body>
<h1 style="margin: auto">
    中国工商银行转账界面
</h1>
<form action="" method="post">
    <table>
        <tr>
            <td>转账给邮箱:</td>
            <td><input type="email" name="email"></td>
        </tr>
        <tr>
            <td>金额:</td>
            <td><input type="text" name="money"></td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="提交"></td>
        </tr>
    </table>
</form>
{{ context.info }}
<ul>
    <button><a href="{% url 'logout' %}">退出登录</a></button>
</ul>
</body>
</html>
posted @ 2020-02-22 23:36  一笑而过~一笑奈何  阅读(192)  评论(0编辑  收藏  举报