zoukankan      html  css  js  c++  java
  • Django的安全机制 CSRF 跨站请求访问

    跨站请求伪造

    一、简介

    django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

    开启此功能后服务端会做两样设置:

      1. 会在cookie中加入 csrftoken字段

      2. 在html模板中 form表单POST请求需加入  {% csrf_token %} 

      注:1. 和2. 生成的字段name和值不一样,但都有效。

    全局:

      中间件 django.middleware.csrf.CsrfViewMiddleware

    settings.py

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]

    局部:

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

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

    二、应用

    1、普通表单

    #veiw中设置返回值:
      return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))  
         或者
         return render(request, 'xxx.html', data)
    # html中设置Token:
      {% csrf_token %}

      html中设置的{% crsf_token %} 渲染后在from表单中生成隐藏的input标签

    <input type="hidden" name="csrfmiddlewaretoken" value="ATvEtmpN8CFuc57eFrnGPjMlIgW2pLQUSKkFAc1FhiSrYbwyI8DuMOv1UubPjxuQ">

      注意:html表单中生成的为token名字为:csrfmiddlewaretoken

    2、Ajax

      对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,使用如下方式。

      view.py

    class SessionLogin(View):
        def get(self, request):
            return render(request, 'session_login.html')
    
        def post(self, request):
            u = request.POST.get('username')
            p = request.POST.get('pwd')
            if u != user.get('username'):
                return render(request, 'session_login.html')
            if p == user.get('password'):
                request.session['current_user'] = u
                request.session.set_expiry(10)
                return redirect('/session_index/')    # form表单提交时可以跳转
                # return HttpResponse('OK') # form表单提交时可以跳转
                # return render(request, 'session_index.html')
            else:
                return render(request, 'session_login.html')

      html中ajax发起POST请求

      关键技术:

           获取:$.cookie('csrftoken')  从cookie中获取csrftoken

           设置:$.ajaxSetup({ beforeSend: function (xhr, settings) {xhr.setRequestHeader('X-CSRFtoken', $.cookie('csrftoken'))})  //ajax请求前设置csrftoken

           临时设置:$.ajax({ headers:{'X-CSRFtoken': $.cookie('csrftoken') }}, ...)

        <script>
            //获取cookie
            //正则语法验证是否是(GET|HEAD|OPTIONS|TRACE)中的任何一种方法,是则返回true
            function csrfSafeMethod(method) {
                // these HTTP methods do not require CSRF protection
                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
            }
    
            function submit() {
                let username = $('#username').val();
                let pwd = $('#pwd').val();
                let data = {'username':username,'pwd':pwd};
                $.ajaxSetup({
                    beforeSend: function (xhr, settings) {
                        // 如果HTTP请求Method 非GET|HEAD...等,并且不是跨域请求,则设置'X-CSRFtoken'请求头
                        if(!csrfSafeMethod(settings.type) && !this.crossDomain){
                            xhr.setRequestHeader('X-CSRFtoken', $.cookie('csrftoken'));
                        }
                        //console.log('this', this);
                        //this为当次ajax请求的全部内容实体对象
                        //console.log('settings.type:',settings.type);
                        //settings.type 当次执行请求时的HTTP-Method
                        //console.log('this.crossDomain:',this.crossDomain);
                    }
                });
    
                $.ajax({
                    url:'/session_login/',
                    data:data,
                    type:'POST',
                    {#headers:{'X-CSRFtoken': $.cookie('csrftoken') }, //请求时临时加入CSRFtoken#}
                    success:function (response_data, textStatus, jqXHR) {
                        {#console.log(textStatus);#}
                        {#console.log(jqXHR.statusText);#}
                        {# window.location.href = '/session_index/';#}
                    }
                });
            }
            $('#submit').click(submit)
        </script>

      

  • 相关阅读:
    Max History CodeForces
    Buy a Ticket CodeForces
    AC日记——字符串的展开 openjudge 1.7 35
    AC日记——回文子串 openjudge 1.7 34
    AC日记——判断字符串是否为回文 openjudge 1.7 33
    AC日记——行程长度编码 openjudge 1.7 32
    AC日记——字符串P型编码 openjudge 1.7 31
    AC日记——字符环 openjudge 1.7 30
    AC日记——ISBN号码 openjudge 1.7 29
    AC日记——单词倒排 1.7 28
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/13355791.html
Copyright © 2011-2022 走看看