django框架——中间件

中间件

自定义中间件

1.在项目名或者应用名下创建一个任意名称的文件夹
2.在该文件夹内创建一个任意名称的py文件
3.在该py文件内需要书写类 类必须继承MiddlewareMixin
	类里面自定义五个方法
	(这五个方法并不是全部都需要书写,用几个写几个)
4.注册到配置文件

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',
    '你自己写的中间件的路径',
]



process_request 
请求来的时候经过每一个中间件里面的process_request方法
如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行
直接原路返回(校验失败不允许访问...)
			
process_response
响应走的时候经过每一个中间件里面的process_response方法
该方法有两个参数request,response
该方法必须返回一个HttpResponse对象
默认返回的就是形参response 也可以自己返回自己的

研究如果在第一个process_request方法就已经返回了HttpResponse对象,
会直接走同级别的process_reponse返回
		

process_view
			路由匹配成功之后执行视图函数之前,
			

process_template_response
			返回的HttpResponse对象有render属性
			
			
process_exception
			当视图函数中出现异常的情况下触发

中间件之csrf

csrf跨站请求伪造

钓鱼网站
	搭建一个跟正规网站一模一样的界面
	用户不小心进入到了我们的网站,用户给某个人打钱
	打钱的操作确确实实是提交给了中国银行的系统,用户的钱也确确实实减少了
	但是唯一不同的时候打钱的账户不适用户想要打的账户变成了一个莫名其妙的账户

	只给用户提供一个没有name属性的普通input框
	然后我们在内部隐藏一个已经写好name和value的input框

如何规避上述问题
	csrf跨站请求伪造校验
		网站在给用户返回一个具有提交数据功能页面的时候会给这个页面加一个唯一标识
		当这个页面朝后端发送post请求的时候 我的后端会先校验唯一标识,如果唯一标识不对直接拒绝(403 forbbiden)如果成功则正常执行

符合校验

form表单

<form action="" method="post">
    {% csrf_token %}
</form>

ajax请求

// 第一种 利用标签查找获取页面上的随机字符串
data:{"username":'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()},
// 第二种 利用模版语法提供的快捷书写
data:{"username":'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
// 第三种 拷贝js代码并应用到html页面
data:{"username":'jason'}

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);
    }
  }
});

csrf相关装饰器

from django.views.decorators.csrf import csrf_protect,csrf_exempt
from django.utils.decorators import method_decorator

csrf_protect  需要校验
    针对csrf_protect 符合的之前三种装饰器
csrf_exempt   忽视校验
    针对csrf_exempt 只有dispatch方法有效

重要编程思想

importlib模块——将字符串当模块导入

import importlib
res = 'myfile.b'
ret = importlib.import_module(res)  # from myfile import b
# 该方法最小只能到py文件名

django中间件,配置文件,字符串导包,重要思想

starts.py

import notify

notify.func('good')

settings.py

app_list = [
    'notify.qq.Q',
    'notify.weixin.W'
]

init.py notify文件夹,包,初始化

import settings
import importlib


def send_all(content):
    for path_str in settings.NOTIFY_LIST:  #'notify.email.Email'
        module_path,class_name = path_str.rsplit('.',maxsplit=1)
        module = importlib.import_module(module_path)  # from notify import email
        cls = getattr(module,class_name)  # Email、QQ、Wechat
        obj = cls()
        obj.send(content)
posted @ 2020-06-03 21:23  pythoner_wl  阅读(171)  评论(0编辑  收藏  举报