django csrf 中间件

CSRF和中间件

CSRF使用

说明csrf存在cookie中

全局使用

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',
]
View Code

局部使用

先导入

from django.views.decorators.csrf import csrf_exempt,csrf_protect
@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
View Code

前端使用

1.通过引入js实现

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('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);
    }
  }
});
View Code

2、作为参数传入

<script>
        var csrftoken = $.cookie('csrftoken');
        $(function () {
            $('#btn').click(function () {
                $.ajax({
                    url:'/login/',
                    type:"POST",
                    data:{'username':'root','pwd':'123123'},
                    header:{'X-CSRFtoken':csrftoken},
                    success:function (arg) {
                        
                    }
                })
            })
        })
    </script>
View Code

3、自定义form引入

{% csrf_token %}
View Code

中间件

1.概述

 定义:中间件是在wsgi之后 urls.py之前 在全局 操作Django请求和响应的模块!

# 中间件的相关设置
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',

    'django.contrib.sessions.middleware.SessionMiddleware',  # request.session

    'django.middleware.common.CommonMiddleware',

    'django.middleware.csrf.CsrfViewMiddleware',

    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'my_middleware.OoXx',
    'my_middleware.MD2',
]
View Code

2.中间件的五种方法

(1) .process_request(self,request)

请求来时执行,不写直接跳过,执行下一个中间件;当有return HttpResonse时,下面中间件不再执行。

执行顺序:
按照注册的顺序(在settings.py里面设置中 从上到下的顺序)
何时执行:
请求从wsgi拿到之后
返回值:
返回None,继续执行后续的中间件的process_request方法
返回response , 不执行后续的中间件的process_request方法

(2) process_view(self, request, callback, callback_args, callback_kwargs) 

先执行process_request,执行完后,再从起始执行proces_view

执行顺序:
按照注册的顺序(在settings.py里面设置中 从上到下的顺序)
何时执行:
在urls.py中找到对应关系之后 在执行真正的视图函数之前
返回值:
返回None,继续执行后续的中间件的process_view方法
返回response,

(3)  process_template_response(self,request,response)

如果Views中的函数返回的对象中,具有render方法,此方法执行

执行顺序:
按照注册顺序的倒序(在settings.py里面设置中 从下到上的顺序)
何时执行:
视图函数执行完,在执行视图函数返回的响应对象的render方法之前
返回值:
返回None,继续执行后续中间件的process_exception
返回response,

(4).  process_exception(self, request, exception)

异常触发执行,当views.py函数执行出错后,此方法执行;出错时,最低层的exception优先级最高,执行最近的一个,然后执行respnse方法

执行顺序:
按照注册顺序的倒序(在settings.py里面设置中 从下到上的顺序)
何时执行:
视图函数中抛出异常的时候才执行
返回值:
返回None,继续执行后续中间件的process_exception
返回response,

(5). process_response(self, request, response)

请求返回时执行,不写时直接跳过,执行下一个中间件;当有return HttpResonse时,会替换原数据

执行顺序:
按照注册顺序的倒序(在settings.py里面设置中 从下到上的顺序)
何时执行:
请求有响应的时候
返回值:
必须返回一个response对象

以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户

Django调用 注册的中间件里面五个方法的顺序:
1. process_request
urls.py
2. process_view
view
3. 有异常就执行 process_exception
4. 如果视图函数返回的响应对象有render方法,就执行process_template_response
5. process_response

3.自定义中间件

创建文件 my_middleware.py

from django.shortcuts import HttpResponse, redirect

"""
自定义的中间件
"""
from django.utils.deprecation import MiddlewareMixin

# 定义一个可以访问的白名单
URL = ["/oo/", "/xx/", "/haha/"]

class OoXx(MiddlewareMixin):

    def process_request(self, request):
        print("这是我的第一个中间件:OoXx!")
        print(id(request))
        # print(request.path_info)
        # # 如果用户访问的URL 在 白名单里面
        # if request.path_info in URL:
        #     return
        # # 否则 直接返回一个 响应 不走视图那部分了
        # else:
        #     return HttpResponse("gun!")

    def process_response(self, request, response):
        """
        :param request: 是浏览器发来的请求对象
        :param response: 是视图函数返回的响应对象
        :return:
        """
        print("这是OOXX中间件里面的 process_response")
        # return response
        return HttpResponse("hahahaha")

    def process_view(self, request, view_func, view_args, view_kwargs):
        """

        :param request: 浏览器发来的请求对象
        :param view_func: 将要执行的视图函数的名字
        :param view_args: 将要执行的视图函数的位置参数
        :param view_kwargs: 将要执行的视图函数的关键字参数
        :return:
        """
        print("ooxx里面的process_view")
        print(view_func, type(view_func))
        return HttpResponse("ooxx:process_view")


    def process_exception(self, request, exception):
        print(exception)
        print("ooxx里面的process_exception")
        return redirect("http://www.baidu.com")

    def process_template_response(self, request, response):
        print("ooxx 中的process_template_response")
        return response

    def process_request(self, request):
       request.s10 = {"is_login": 1, "name": "s10"}



class MD2(MiddlewareMixin):

    # def process_request(self, request):
    #     print("这是我的第二个中间件:MD2!")
    #     print(id(request))
    #
    # def process_response(self, request, response):
    #     print("这是MD2中间件里面的 process_response")
    #     return response
    #
    # def process_view(self, request, view_func, view_args, view_kwargs):
    #     print("MD2里面的process_view")
    #     print(view_func, type(view_func))
    #     return HttpResponse("md2:process_view")

    # def process_exception(self, request, exception):
    #     print(exception)
    #     print("MD2里面的process_exception")

    # def process_template_response(self, request, response):
    #     print("MD2 中的process_template_response")
    #     return response


    def process_request(self, request):
       print(request.s10.get("is_login"))
View Code

 注册

# 中间件的相关设置
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',

    'django.contrib.sessions.middleware.SessionMiddleware',  # request.session

    'django.middleware.common.CommonMiddleware',

    'django.middleware.csrf.CsrfViewMiddleware',

    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'my_middleware.OoXx',
    'my_middleware.MD2',
]
View Code

 请求测试

from django.shortcuts import render, HttpResponse, redirect

# Create your views here.


def index(request):
    print("这是app01里面的index视图函数...")
    # raise ValueError("sb")
    rep = HttpResponse("O98K")
    print("视图函数中的s10:", request.s10)
    def render():
        print("我是index视图函数内部的render方法")
        return redirect("http://www.luffycity.com")

    rep.render = render
    return rep
View Code
原文地址:https://www.cnblogs.com/huay/p/11592721.html