方式一:
django模板标签提供{% csrf_token %}在前端生成input框,如果在settings.py文件中开启了该中间件,每次post请求就需要提交django自动生成的csrfToken;
将{% csrf_token %}生成的input框的value通过ajax传参来提交;
{% csrf_token %} <!-- django模板标签提供的csrf_token值,会自动生成一个input框--> <script> $("#button_name").on("click",function{ var name = $("#name").val(); var csrfToken = $("[name="csrfmiddlewaretoken"]").val(); $.ajax({ url: "/ajax_res/", // 请求视图 type: "post", // 请求方式 // 携带数据,从{% csrf_token %}input框中获取csrfToken值,通过ajax方式提交后台,否则报错:Forbidden(CSRF token missing or incorrect.) data: {"name": name, "csrfmiddlewaretoken": csrfToken} success: function(args){ alert(args) // 返回数据 //... } }); }); </script>
方式二:
从获取当前页面的get请求的响应中cookie里获取csrfToken,再写入当前post请求的请求头中;
需要引入:jquery.cookie.js插件
<script> $.ajax({ url: "/ajax_res/", type: "post", headers: {"X-CSRFToken":$.cookie("csrftoken")}, data: {"name": name} success: function(args){ alert(args) //... } }); </script>
方式三:
与方式二原理相同,手写从cookie中获取/写入csrfToken的js文件,再引入,就不需要做其他参数传递,同get请求一般;
// ajaxSetup.js
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 csrftoken = getCookie('csrftoken'); // 2.定义不需要csrftoken的请求方式 function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } // 3.将csrftoken写入当前请求头 $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });
方式四:
在ajax请求前加上;
<script> $.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}'}, }); </script>
下面讲述django中csrf的使用:
django中csrf_token有两种提交方式,一种是在template模板中使用{% csrf_token %}生成一个input框在form表单中提交或者将csrf_token值通过ajax提交;
一种是将csrf写入cookie中;
就是上面讲述的方式;
在django中开启csrf跨站请求保护:
1.开启django.middleware.csrf.CsrfViewMiddleware中间键(django默认在settings.py中已经开启了);
2.将1.中的中间键注释掉,对指定视图添加跨站请求保护,通过django.views.decorators.csrf import csrf_protect装饰器来启用当前视图(@csrf_protect);
在django中其他与csrf有关的装饰器:
1.csrf_exempt(view)装饰器,免除csrf跨站保护;
使用场景:大部分视图需要保护,小部分不需要,开启CsrfViewMiddleware中间键,同时使用csrf_exempt(view)免除不需要保护的视图;
2.requires_csrf_token(view)装饰器,用以确认前端form表单中是否通过{% csrf_token %}传递值过来,但是不拒绝请求;
使用场景01:在某些情况下,比如CsrfViewMiddleware.process_view没有在视图运行前执行,造成404/500等错误(拒绝请求),但是我们仍然需要csrf_token的值做一些其他的处理,
就可以使用requires_csrf_token(view)(不拒绝请求);
使用场景02:与场景01不同,不是某些异常情况,而是本身当前视图就不需要保护,但是仍然需要使用csrf_token做一些判断处理,就可以使用requires_csrf_token(view)与csrf_exempt(view)
来实现,注意是先执行requires_csrf_token(view)装饰器(csrf_exempt(view)写在上面);
@csrf_exempt
@requires_csrf_token
def index_view:
3.ensure_csrf_cookie(view)装饰器,表示当前视图请求必须将csrf写在cookie中;
csrf的注意事项:
如果django中开启了缓存中间件,单独使用cache_page(view)缓存装饰器的视图中跨站请求保护将会失效,需要在cache_page(view)前执行csrf_protect(view)装饰器;
@cache_page(60*15)
@csrf_protect
def index_view...