Python developers [Django]: middleware, CSRF

Python developers [Django]: middleware, CSRF

CSRF

1 Overview

  CSRF (Cross Site Request Forgery) cross-site request forgery, for example in terms of, there is a link to your site, if a user has to log on to your site, then when the user clicks on a malicious Web site that when the link on a malicious Web site, a request will be sent to your site, your site will think that this request is sent to the user's own, actually, this request is that a malicious fake website.

  To avoid the above situation, cited Django CSRF protection mechanisms; Django when the first response to a request from a client, it will randomly generate a token on the server side, and put the token in a cookie. POST requests are then each time will bring the token, so as to avoid being CSRF attacks. If there are no POST request token random string, it returns a denial of service 403

  • In the cookie HTTP response returned inside, django will add a csrftoken field for you, whose value is automatically generated by a token
  • When all of the POST form, must contain a csrfmiddlewaretoken field (only one template tag in Riga, django will automatically help you generate, see below)
  • Values ​​and submitted in the form of csrfmiddlewaretoken field before the POST request is processed, django will verify the request of the cookie in the field of csrftoken whether the same. If, as it indicates that this is a legitimate request, otherwise, the request may come from someone else's csrf attack, returns 403 Forbidden.
  • In all ajax POST request, which add a X-CSRFTOKEN header, the value of a cookie whose value is csrftoken

Now we need to enable middleware django.middleware.csrf.CsrfViewMiddleware in settings.py:

`MIDDLEWARE ``=` `[``    ``'django.middleware.csrf.CsrfViewMiddleware'``,``]`

Local use:

  • @csrf_protect, forced to current function CSRF prevention function, even if the settings are not set the overall middleware.
  • @csrf_exempt, cancels the current function CSRF prevention function, even if the global settings set in the middleware.

CBA in use:

`from` `django.utils.decorators ``import` `method_decorator``class` `AssetView(View):``    ``@method_decorator``(csrf_exempt)     ``#必须加到dispatch上,get、post上都不好使``    ``def` `dispatch(``self``, request, ``*``args, ``*``*``kwargs):``        ``return` `super``(AssetView, ``self``).dispatch(request, ``*``args, ``*``*``kwargs)`

  

2, Form Request POST form submissions

With files:

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    elif request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'root' and pwd == "123":
            # 生成随机字符串
            # 写到用户浏览器Cookie
            # 保存到Session中
            # 在随机字符串对应的字典中设置相关内容...
            request.session['username'] = user
            request.session['if_login'] = True  #可不加 直接判断username也可以
            if request.POST.get('session') == '1':    #单独设置超时时间,当前session生效,不影响全局
                request.session.set_expiry(10)      #10秒
            return redirect('/index/')
        else:
            return redirect('/login/')

def index(request):
    # 获取当前用户的随机字符串
    # 根据随机字符串获取对应信息
    if request.session.get('if_login'):
        return render(request, 'index.html')
    else:
        return redirect('/login/')

login.html file:

`{``# 添加{% csrf_token %} #}``<!DOCTYPE html>``<html lang``=``"en"``>``<head>``    ``<meta charset``=``"UTF-8"``>``    ``<title>Title<``/``title>``<``/``head>``<body>``    ``<form action``=``"/login/"` `method``=``"post"``>``        ``{``%` `csrf_token ``%``}``        ``<``input` `type``=``"text"` `name``=``"user"` `/``>``        ``<``input` `type``=``"text"` `name``=``"pwd"` `/``>``        ``<``input` `type``=``"checkbox"` `name``=``"session"` `value``=``"1"``/``> 保存``1``个月``        ``<``input` `type``=``"submit"` `value``=``"提交"` `/``>``    ``<``/``form>``<``/``body>``<``/``html>`

3, Ajax submits a POST request

With files:

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.
def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    elif request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'root' and pwd == "123":
            # 生成随机字符串
            # 写到用户浏览器Cookie
            # 保存到Session中
            # 在随机字符串对应的字典中设置相关内容...
            request.session['username'] = user
            request.session['if_login'] = True  #可不加 直接判断username也可以
            if request.POST.get('session') == '1':    #单独设置超时时间,当前session生效,不影响全局
                request.session.set_expiry(10)      #10秒
            return redirect('/index/')
        else:
            return redirect('/login/')

def index(request):
    # 获取当前用户的随机字符串
    # 根据随机字符串获取对应信息
    if request.session.get('if_login'):
        return render(request, 'index.html')
    else:
        return redirect('/login/')

login.html file:

`{``# Ajax提交时要添加headers值 #}``<!DOCTYPE html>``<html lang``=``"en"``>``<head>``    ``<meta charset``=``"UTF-8"``>``    ``<title>Title<``/``title>``<``/``head>``<body>``    ``<form action``=``"/login/"` `method``=``"post"``>``        ``{``%` `csrf_token ``%``}               ``        ``<``input` `type``=``"text"` `name``=``"user"` `/``>``        ``<``input` `type``=``"text"` `name``=``"pwd"` `/``>``        ``<``input` `type``=``"checkbox"` `name``=``"session"` `value``=``"1"``/``> 保存``1``个月``        ``<``input` `id``=``'btn'` `type``=``"button"` `value``=``"Ajax提交"` `/``>``    ``<``/``form>``    ``<script src``=``"/static/jquery-1.12.4.js"``><``/``script>``    ``<script src``=``"/static/jquery.cookie.js"``><``/``script>``    ``<script>``        ``$(function () {``            ``$(``'#btn'``).click(function () {``                ``$.ajax({``                    ``url:``'/login/'``,``                    ``type``:``'POST'``,``                    ``data:{``'user'``:``'root'``,``'pwd'``:``'123'``},``                    ``headers:{``'X-CSRFtoken'``:$.cookie(``'csrftoken'``)},``                    ``success:function (arg) {``                    ``}``                ``})``            ``})``        ``})``    ``<``/``script>``<``/``body>``<``/``html>`

After the above html file click Submit, successful execution; but often a program is more than an Ajax request, so we all need to add headers Ajax request header for each request, so too enormous amount of work; then you need to make global settings, you do not have every a request headers are added

{# Ajax提交时全局生效 #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login/" method="post">
        {% csrf_token %}
        <input type="text" name="user" />
        <input type="text" name="pwd" />
        <input type="checkbox" name="session" value="1"/> 保存1个月
        <input id='btn' type="button" value="Ajax提交" />
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>
        $(function () {
{#            全局配置,所有Ajax请求都先执行下面操作#}
            $.ajaxSetup({
                beforeSend:function (xhr,settings) {
                    xhr.setRequestHeader('X-CSRFtoken',$.cookie('csrftoken'));
                }
            });

            $('#btn').click(function () {
                $.ajax({
                    url:'/login/',
                    type:'POST',
                    data:{'user':'root','pwd':'123'},
                    success:function (arg) {

                    }
                })
            })
        })
    </script>
</body>
</html>
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    {% csrf_token %}
  
    <input type="button" onclick="Do();"  value="Do it"/>
  
    <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
    <script src="/static/plugin/jquery/jquery.cookie.js"></script>
    <script type="text/javascript">
        var csrftoken = $.cookie('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);
                }
            }
        });
        function Do(){
  
            $.ajax({
                url:"/app01/test/",
                data:{id:1},
                type:'POST',
                success:function(data){
                    console.log(data);
                }
            });
  
        }
    </script>
</body>
</html>

Middleware

1 Overview

  in django middleware (middleware), in django, the middleware is actually a class, and after the arrival of the request, django middleware corresponding method will be executed at the right time according to their own rules; settings in django projects module, a variable mIDDLEWARE, wherein each element is an intermediate, is as follows:

`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'``,``]`

Middleware can define four methods are:

  • process_request (self, request) to the execution request, when the skip is not written, a next intermediate performed; when a return HttpResonse, the following intermediate is not executed
  • process_view (self, request, callback, callback_args, callback_kwargs) process_request first implementation, after the implementation, starting again from the execution proces_view
  • process_template_response (self, request, response) if the object is returned in function Views having render method, this method is performed
  • process_exception (self, request, exception) performed trigger abnormal, when the function execution error views.py, this method is performed; when an error occurs, the lowest level of the highest priority exception, a recent execution, and execution method respnse
  • process_response (self, request, response) returns execution request, when the skip is not written, a next intermediate performed; when a return HttpResonse, replaces original data

Return value None of the above method may be HttpResonse objects and, if it is None, then continues down django defined according to the rules, if HttpResonse the object, the object is returned directly to the user

img

Note: the same level of direct execution process_response after Django version 1.10 instead started from the lowest process_response

2, custom middleware

Create a directory middleware (name any) under Django's home directory, create a file in the directory m.py

① process_request、process_response

Custom middleware class in the file:

`from` `django.utils.deprecation ``import` `MiddlewareMixin``from` `django.shortcuts ``import` `HttpResponse` `class` `Row1(MiddlewareMixin):``    ``def` `process_request(``self``,request):``        ``print``(``"王森1"``)``        ``# return HttpResponse("DDDD")``    ``def` `process_response(``self``,request,response):``        ``print``(``"扛把子1"``)``        ``return` `response` `class` `Row2(MiddlewareMixin):``    ``def` `process_request(``self``,request):``        ``print``(``"王森2"``)``    ``def` `process_response(``self``, request, response):``        ``print``(``"扛把子3"``)``        ``return` `response` `class` `Row3(MiddlewareMixin):``    ``def` `process_request(``self``,request):``        ``print``(``"王森3"``)``    ``def` `process_response(``self``, request, response):``        ``print``(``"扛把子3"``)``        ``return` `response`

Sign middleware settings file:

`from` `django.middleware.csrf ``import`  `CsrfViewMiddleware``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'``,``    ``'middleware.m.Row1'``,``    ``'middleware.m.Row2'``,``    ``'middleware.m.Row3'``,`

Printing is performed: 

王森1
王森2
王森3
走你
扛把子3
扛把子3
扛把子1

② process_view

Custom middleware class in the file:

`from` `django.utils.deprecation ``import` `MiddlewareMixin``from` `django.shortcuts ``import` `HttpResponse` `class` `Row1(MiddlewareMixin):``    ``def` `process_request(``self``,request):``        ``print``(``"王森1"``)``    ``def` `process_view(``self``, request, view_func, view_func_args, view_func_kwargs):``        ``print``(``"James1"``)``    ``def` `process_response(``self``,request,response):``        ``print``(``"扛把子1"``)``        ``return` `response` `class` `Row2(MiddlewareMixin):``    ``def` `process_request(``self``,request):``        ``print``(``"王森2"``)``    ``def` `process_view(``self``, request, view_func, view_func_args, view_func_kwargs):``        ``print``(``"James2"``)``    ``def` `process_response(``self``, request, response):``        ``print``(``"扛把子3"``)``        ``return` `response` `class` `Row3(MiddlewareMixin):``    ``def` `process_request(``self``,request):``        ``print``(``"王森3"``)``    ``def` `process_view(``self``, request, view_func, view_func_args, view_func_kwargs):``        ``print``(``"James3"``)``    ``def` `process_response(``self``, request, response):``        ``print``(``"扛把子3"``)``        ``return` `response`

Printing is performed:

王森1
王森2
王森3
James1
James2
James3
走你
扛把子3
扛把子3
扛把子1

Guess you like

Origin www.cnblogs.com/TMesh/p/11735928.html