django—csrf中间件

1、作用

1、渲染本网站的前端form表单时,会生成一个字符串来标识该form表单

2、当form表单发起post请求,提交数据时,会携带该参数,后端的csrf中间件就会拿后端保存的字符串进行比对

3、验证通过,代表发起post请求的确实是本网站的前端,否则不是

4、该字符串在前端form表单中,被渲染成一个隐藏的input框

<input type="hidden" name="csrfmiddlewaretoken" value="随机字符串">

2、如何使用

2.1 form表单发起post请求

编写html代码时,只需要在form标签内,使用模板语法{% csrf_token %}即可,浏览器会自动渲染出一个隐藏的input框

<form action="" method="post">
	{% csrf_token %}
	<p>username:<input type="text" name="username"></p>
	<p>target_account:<input type="text" name="target_user"></p>
	<p>money:<input type="text" name="money"></p>
	<input type="submit">
</form>

2.2 ajax发起post请求

结合forms表单演示

1、添加键值对到data字典中

<!--form标签-->
{% for transfer in transfer_obj %}
    {{ transfer.label }}{{ transfer }}
    <span>{{ transfer_obj.errors.0 }}</span>
{% endfor %}
<input type="submit" value="提交" id="d1">
{% csrf_token %}


<!--ajax
方式1:可以通过查找标签获取值的方式添加到data字典中,如username
方式2:针对csrf_token,可以直接使用模板语法{{csrf_token}}
-->

<script>
    $('#d1').click(function () {
        $.ajax({
            url:'',
            type:'post',
            data:{'username':$('#id_username').val(), 'target_user':$('#id_target_user').val(),
            'money':$('#id_money').val(), 'csrfmiddlewaretoken':'{{ csrf_token }}'},
            success:function (data) {
                alert('提交成功')
            }
        })
    })
</script>

2、利用官网提供的文件

将下面的js文件拷贝到项目的静态文件夹下即可

在html页面通过导入该文件即可自动帮我们解决ajax提交post数据时校验csrf_token的问题,(导入该配置文件之前,需要先导入jQuery,因为这个配置文件内的内容是基于jQuery来实现的)

// setup.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');

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);
    }
  }
});

3、csrf相关的装饰器

需要导入模块

from django.views.decorators.csrf import csrf_exempt,csrf_protect

两种装饰器的区别

@csrf_exempt  # 不校验 csrf
def index(request):
	return HttpResponse('index')


@csrf_protect  # 校验
def login(request):
	return HttpResponse('login')

在CBV上的区别

# csrf_exempt
# csrf_exempt这个装饰器只能给dispatch装才能生效

@method_decorator(csrf_exempt,name='dispatch')  # csrf_exempt加载类上面,指定dispatch
class MyIndex(views.View):
	# @method_decorator(csrf_exempt)  # 也可以直接加给dispatch
	def dispatch(self, request, *args, **kwargs):
		return super().dispatch(request,*args,**kwargs)
	
    def get(self,request):
		return render(request,'transfer.html')

	def post(self,request):
		return HttpResponse('OK')		


"""
csrf_protect方式全都可以  跟你普通的装饰器装饰CBV一致
"""
@method_decorator(csrf_protect,name='post')  # 可以
class MyIndex(views.View):
	def dispatch(self, request, *args, **kwargs):
		return super().dispatch(request,*args,**kwargs)
	
    def get(self,request):
		return render(request,'transfer.html')

	def post(self,request):
		return HttpResponse('OK')

posted @ 2019-12-05 23:34  W文敏W  阅读(163)  评论(0编辑  收藏  举报