Django 中 CSRF 理解与使用

Django 中 CSRF 理解

一、CSRF 使用:

Django 为用户实现防止跨站请求伪造的功能,通过中间件django.middleware.csrf.CsrfViewMiddleware来完成。

全局设置中间件:

# 在setting.py 中 默认django 框架就会开启配置项
MIDDLEWARE = [
    'django.middleware.csrf.CsrfViewMiddleware',
]

局部:

1.FBV模式局部使用:

  • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

    # 'django.middleware.csrf.CsrfViewMiddleware', # 需要注释这一句话
    
    from django.views.decorators.csrf import csrf_exempt,csrf_protect
    
    @csrf_protect
    def csrf_test(request):
        if request.method == 'GET':
            return render(request,'csrf_test.html')
        else:
            return HttpResponse('ok')
    
  • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

    'django.middleware.csrf.CsrfViewMiddleware',   # 不注释
    
    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt
    def csrf_test(request):
    
        if request.method == 'GET':
            return render(request,'csrf_test.html')
        else:
            return HttpResponse('ok')
    
  • 导入:from django.views.decorators.csrf import csrf_exempt,csrf_protect

2.CBV模式局部使用:

  • 局部禁用:在dispatch()方法上面添加 @csrf_exempt

    from django.utils.decorators import method_decorator
    from django.views.decorators.csrf import csrf_exempt, csrf_protect
    from django.shortcuts import render, HttpResponse
    from django.views import View
    class CsrfViews(View):
        @csrf_exempt 
        def dispatch(self, request, *args, **kwargs):
            return super().dispatch(request, *args, **kwargs)
    
        def get(self, request, *args, **kwargs):
            return HttpResponse('GET,响应内容')
    
        def post(self, request, *args, **kwargs):
            return HttpResponse('Post,响应内容')
    
  • 局部使用:同样在dispatch()方法上添加django内置装饰器@method_decorator,将csrf_protect传入:

    from django.views.decorators.csrf import csrf_exempt, csrf_protect
    from django.utils.decorators import method_decorator
    from django.shortcuts import render, HttpResponse
    from django.views import View
    class CsrfViews(View):
        @method_decorator(csrf_protect)
        def dispatch(self, request, *args, **kwargs):
            return super().dispatch(request, *args, **kwargs)
    
        def get(self, request, *args, **kwargs):
            return HttpResponse('GET,响应内容')
    
        def post(self, request, *args, **kwargs):
            return HttpResponse('Post,响应内容')
    
  • method_decorator的使用:

    name:这个参数是必备的,是为了装饰类中的get方法还是post方法

    from django.utils.decorators import method_decorator
    
    # 将整个类都禁用,name='dispatch',无论什么方式请求,分发时都禁用
    @method_decorator(csrf_exempt, name='dispatch')
    class CsrfViews(View):
    
        def get(self, request, *args, **kwargs):
            return HttpResponse('GET,响应内容')
    
        def post(self, request, *args, **kwargs):
            return HttpResponse('Post,响应内容')
    

二、原理:

当使用post提交数据时,Django会去检查是否有一个csrf的随机字符串,如果没有就会报错,这也是上面我们提到要禁用或注释的原因:
Django 中 CSRF 理解与使用_第1张图片

三、通过FORM表单提交:

form表单里面需要加{% csrf_token %}
Django 中 CSRF 理解与使用_第2张图片
总结:当用户访问/login页面的时候,会自动生成一个csrf随机字符串,并且cookie中也存放这个随机字符串,当用户再次提交数据的时候会带的这个随机字符串提交。

四、通过Ajax提交:

如果通过ajax进行提交数据,这里提交的csrftoken是通过请求头中存放,需要提交一个字典类型的数据,即这个时候需要一个key。

$("#btn1").click(function () {
       $.ajax({
           url:"/login/",
           type:"POST",
           data:{"usr":"root","pwd":"123456"},
           # 因为cookie中同样存在csrftoken,所以value,可以直接从cookie中取
           headers:{ "X-CSRFtoken":$.cookie("csrftoken")},
           success:function (arg) {

           }
       })
   })

五、总结:

1.csrf在ajax提交的时候通过请求头传递给后台,通过key、value形式。

2.csrf在前端的key为:X-CSRFtoken,到后端的时候django会自动添加HTTP_,并且最后为HTTP_X_CSRFtoken。

3. csrf在form中提交的时需要在前端form中添加 {% csrftoken %} 。

你可能感兴趣的:(Django)