zoukankan      html  css  js  c++  java
  • 十六 .Django CSRF的解决

     

    一 .Django之CSRF

    1.CSRF 简介

    跨站请求伪造(CSRF)与跨站请求脚本正好相反。跨站请求脚本的问题在于,客户端信任服务器端发送的数据。跨站请求伪造的问题在于,服务器信任来自客户端的数据。
    无CSRF时存在的隐患
    跨站请求伪造是指攻击者通过HTTP请求江数据传送到服务器,从而盗取回话的cookie。盗取回话cookie之后,攻击者不仅可以获取用户的信息,
    还可以修改该cookie关联的账户信息。

    2. CSRF在Django中

    django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。
    而对于django中设置防跨站请求伪造功能有分为全局和局部。 全局: 中间件 django.middleware.csrf.CsrfViewMiddleware 局部: @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。 @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。 注意:
    from django.views.decorators.csrf import csrf_exempt,csrf_protect

     3. 处理csrf四种方法

    django 第一次响应来自某个客户端的请求时(get方式),会在服务器端随机生成一个 token,然后把这个 token 写在用户请求的 cookie 里,同时也会给客户端页面发送一个随机的 token (form表单中以{% csrf_token %}方式获取)用以认证。之后客户端每次以 POST 方式向服务端提交请求时,都会带上这个 token,这样就能避免被 CSRF 攻击。
    
      1.在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token;
      
    2.在所有的 POST 表单中,必须包含一个 csrfmiddlewaretoken 字段 (只需要在模板里加一个 tag, django 就会自动帮你生成,见下面)
      
    3.在处理 POST 请求之前,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否一样
    。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden.
      
    4.在所有 ajax POST 请求里,添加一个 X-CSRFTOKEN header,其值为 cookie 里的 csrftoken 的值

    4. 基本应用

    
                直接在form表单中添加:就能应用。
                {% csrf_token %} -----> 转换成一个hidden属性的input标签
                {{ csrf_token }} -----> 直接获取csrf的随机字符串
                 
                注意:本地的cookies中也会添加随机字符串 ---> 注意key名

    5 .全站禁用:

    - 整个框架不使用csrf安全机制,直接在settings.py文件中注销,整个网站都不再应用。
            # 'django.middleware.csrf.CsrfViewMiddleware',

    6 .局部禁用:全局使用,但是某些函数不需要应用

     - settings.py文件中不注销,在项目的views.py函数中导入模块,给函数或是类加上对应方法的装饰器:
            'django.middleware.csrf.CsrfViewMiddleware',
             
            from django.views.decorators.csrf import csrf_exempt,csrf_protect
     
            @csrf_exempt   #不再做检测!其他没加装饰器的函数还是会检测
            def csrf1(request):
     
                if request.method == 'GET':
                    return render(request,'csrf1.html')
                else:
                    return HttpResponse('ok')

    7. 局部使用:全局不使用,但是某些函数需要应用

    # 'django.middleware.csrf.CsrfViewMiddleware',
             
            from django.views.decorators.csrf import csrf_exempt,csrf_protect
     
            @csrf_protect  #全站不用,某个函数需要使用认证的时候
            def csrf1(request):
     
                if request.method == 'GET':
                    return render(request,'csrf1.html')
                else:
                    return HttpResponse('ok')

    8 .特殊CBV:在CBV应用中

        django 不认给类内的函数名上添加装饰器,只能是在类上添加。
        同时django限制若是应用装饰器,必须用它的方法去添加,同时添加的语法格式也有限制。
    from django.views import View
                from django.utils.decorators import method_decorator  #必须使用这个方法
                    - 语法:@method_decorator(装饰器函数名称或方法,name='被装饰的函数名')
     
                #先导入方法,然后装饰器以参数的形式添加,其次指定要添加这个方法的函数名<样式:name="函数名">
                         
                @method_decorator(csrf_protect,name='dispatch')
                class Foo(View):
                    #请求来了,都是先执行类View的内置函数dispatch,然后再映射到对应的方法上!
                    #所以给dispatch添加上就相当于给所有的方法添加了
                    def get(self,request):
                        pass
     
                    def post(self,request):
                        pass
       PS:CBV中添加装饰器
    #自定义的装饰器 def wrapper(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner # 1. 指定方法上添加装饰器 class Foo(View): @method_decorator(wrapper) #先导入方法,然后装饰器以参数的形式添加 def get(self,request): pass def post(self,request): pass # 2. 在类上添加 @method_decorator(wrapper,name='dispatch') class Foo(View): def get(self,request): pass def post(self,request): pass

    9. Ajax提交数据时候,携带CSRF

     以post方式提交,放置在data中携带
    <form method="POST" action="/csrf1.html">
                    {% csrf_token %}
                    <input id="user" type="text" name="user" />
                    <input type="submit" value="提交"/>
                    <a onclick="submitForm();">Ajax提交</a>
                </form>
                <script src="/static/jquery-1.12.4.js"></script>
                <script>
                    function submitForm(){
                        var csrf = $('input[name="csrfmiddlewaretoken"]').val();
                        var user = $('#user').val();
                        $.ajax({
                            url: '/csrf1.html',
                            type: 'POST',
                            data: { "user":user,'csrfmiddlewaretoken': csrf}, 
                                        #注意csrf随机字符串,后台有固定的名字接收,这种方式是通过标签获取的对应值                                                                    success:function(arg){
                                console.log(arg);
                            }
                        })
                    }
     

    10 . AJAX 中POST方式提交,信息放在请求头中,从cookies中获取的csrf随机字符串

           <form method="POST" action="/csrf1.html">
                        {% csrf_token %}
                        <input id="user" type="text" name="user" />
                        <input type="submit" value="提交"/>
                        <a onclick="submitForm();">Ajax提交</a>
                    </form>
                    <script src="/static/jquery-1.12.4.js"></script>
                    <script src="/static/jquery.cookie.js"></script>
     
                    <script>
                        function submitForm(){
                            var token = $.cookie('csrftoken');
                            var user = $('#user').val();
                            $.ajax({
                                url: '/csrf1.html',
                                type: 'POST',
                                headers:{'X-CSRFToken': token},  #注意csrf随机字符串后台有固定的名字接收
                                data: { "user":user},
                                success:function(arg){
                                    console.log(arg);
                                }
                            })
                        }
                    </script>

    11. django csrf注意点

    注意一定注意:ajax POST提交的时候,csrf-token 随机字符串 直接放在data数据中的方式为:data:{csrfmiddlewaretoken:"{{ csrf_token }}"}
     
    
      若是导入自己写的JS文件,那上述方法就不能获取到Django后台发送的随机字符串,而是需要利用上面介绍的两种方式获取(页面写上{% csrf_token %},通过隐藏的input标签取value值写在POST
    提交的data数据中;或是从cookie中获取,写在头文件中。) 使用django框架时:   每次初始化一个项目时都要看看 django.middleware.csrf.CsrfViewMiddleware 这个中间件   每次在模板里写 form 时都需要加一个 {
    % csrf_token %} tag   每次发 ajax POST 请求,都需要加一个 X_CSRFTOKEN 的 head

     

  • 相关阅读:
    求职方法论
    测试经验与教训_学习笔记
    测试架构师修炼之道_学习笔记
    Jmeter测试oracle
    Jmeter 非UI界面jmx脚本不能正常退出
    Jmeter参数化的理解
    jmeter 测试并发
    Jmeter测试数据库
    pytorch runtime error: CUDNN_STATUS_MAPPING_ERROR
    Python/pytorch 切换国内源/AttributeError: module 'torch.jit' has no attribute 'unused'/not a trusted or secure host
  • 原文地址:https://www.cnblogs.com/lovershowtime/p/11361441.html
Copyright © 2011-2022 走看看