Django: post请求怎么满足CSRF保护机制?
2017-12-17 本文已影响77人
fall4u
什么是CSRF
CSRF是英文 cross-site request forgery的简写, 中文翻译为跨站伪造请求。对CSRF的详细描述,可以参考这里。 为了在用户在访问网站的时候,避免受到CSRF的攻击。Django默认开启了
CSRF的保护功能。
异常情况说明
如果前端浏览器没有按照Django的要求发送POST/DELETE/PUT请求的时候, Django会返回403错误。
在浏览器打开开发者调试工具,我们可以看到以下错误提示:
127.0.0.1/:3495 POST http://127.0.0.1:8000/sku/skuimport/ 403 (Forbidden)
在服务器端也会看到以下错误提示:
Forbidden (CSRF token missing or incorrect.): /sku/skuimport/
[17/Dec/2017 04:48:44] "POST /sku/skuimport/ HTTP/1.1" 403 2502
处理方法:
Django官网对相应的处理办法有详细说明
Step1: 获得 csrf_token的值
var csrftoken = Cookies.get('csrftoken');
Step2: 将csrf_token的值设置在http的头部
Django官网所给出的方法是:
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
主要是针对除GET/HEAD/OPTIONS/TRACE这些以下的请求, 在发送请求之前给http request添加额外的头部信息X-CSRFToken,这个值就是在步骤1中获取的值呢。
Step3: 发送请求
接下来就可以使用API jQuery.post( url [, data ] [, success ] [, dataType ] )发送请求呢
$.post( "ajax/test.html", function( data ) {
$( ".result" ).html( data );
});
注意:
在使用XMLHttpRequest发送数据的时候, 此方法并不能生效。 需要在调用send方法之前, 显式设置http request的头部信息。
// Get an XMLHttpRequest instance
var xhr = new XMLHttpRequest();
// Set up request
xhr.open('POST', uri, true);
xhr.setRequestHeader("X-CSRFToken",csrftoken);
// Fire!
xhr.send(formData);