在普通的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>