• Django SCRF跨站点请求伪造


      使用Django发POSTt请求的时候经常会遇到Forbidden的错误,然后直接了当的方法就是去setting里面吧csrf中间件注释掉,其实csrf是django给我们提供的防护措施.

      CSRF就是一种攻击方式,原理大概是你去A网站登录后本地留下了A网站的cookie,然后去B网站访问收到了CSRF的攻击,拿到了你A网站的cookie,然后攻击者用这个cookie去请求A网站,盗取你的信息财物等.

      具体这个博客写得很好:戳CSRF

      这里我们主要讲django 中csrf防护的原理和设置.

    1.csrf防护在Django中就是一个中间件,生成token验证,token验证就是你要拿到一张牌(一串字符串),django认识这个字符串,才让你访问.

    #django 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',
    ]

    2.Form请求中的csrf:

    我们写好一盒form表单,提交方式写为post的时,点提交会出现以下页面:

    Forbidden (403) CSRF verification failed. Request aborted. Help Reason given for failure: CSRF token missing or incorrect. In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:   Your browser is accepting cookies.   The view function passes a request to the template's render method.   In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.   If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.   The form has a valid CSRF token. After logging in in another browser tab or hitting the back button after a login, you may need to reload the page with the form, because the token is rotated after a login. You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed. You can customize this page using the CSRF_FAILURE_VIEW setting.

    错误中也说明了解决方式:在form表单中加入{% csrf_token %}:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="/fm001/myCSRF/"  method="post">
        name: <input type="text">
        <input type="submit" value="提交">
        {% csrf_token %}
    
    </form>
    </body>
    </html>

    我们再发post请求就可以了,检查发现{% csrf_token %} 在页面上生成了这串东西, 我们提交请求的时候会带着这个东西去请求,而这个东西就是django给我的,django会识别是不是这货

    3:Ajax请求中的csrf:

    写好html页面:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="/static/jquery-3.2.1.min.js"></script>
    </head>
    <body>
    <form action="/fm001/myCSRF/"  method="post">
        name: <input type="text">
        <input type="submit" value="提交">
    
        <input id="but" type="button" value="ajax提交">
    </form>
    </body>
    <script>
        $("#but").click(function () {
             $.ajax({
                url:"/fm001/myCSRF/",
                type:"POST", 
                 data:{"xx":"yy"},
                success:function (arg) {
                    alert("ok")
                }
    
    
             })
        })
    </script>
    </html>

    提交后出现如下错误:Forbidden (CSRF token missing or incorrect.): /fm001/myCSRF/

    这就是我们没有提交token给django,需要在请求头里面加上token值,用jq获取cookie,所以导入jquery.cookie.js 具体:

    <script>
        $("#but").click(function () {
             $.ajax({
                url:"/fm001/myCSRF/",
                type:"POST",
                 data:{"xx":"yy"},
                 headers:{"X-CSRFToken":$.cookie("csrftoken")},
                success:function (arg) {
                    alert("ok")
                }
    
    
             })
        })
    </script>
    

    这样提交就可以了.

    为了方便,不每次发ajax请求都去写headers,可以设置ajax请求每次发送之前加上添加token到headers的操作:

     $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
            });

    当然的django中也可以试着那些请求需要token,那些不需要,django提供了装饰器:

    from dajngo.views.decorators.csrf import csrf_protect,csrf_exempt
    @csrf_protect,#为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。加载views函数上就可以了.
    @csrf_exempt,#取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

     

  • 相关阅读:
    第12组 Alpha冲刺(4/6)
    第12组 Alpha冲刺(3/6)
    第12组 Alpha冲刺(2/6)
    2019软件工程实践——第四次作业
    2019软件工程实践——第三次作业
    2019软件工程实践——第二次作业
    2019软件工程实践——第一次作业
    博客园 自定义背景图片(包括动图)
    软件工程 实验一 GIT代码版本管理
    WordCounter项目(基于javase)
  • 原文地址:https://www.cnblogs.com/guoguojj/p/8395416.html
Copyright © 2020-2023  润新知