文章目录

  • 1.django中间键
    • 1.1 七层中间键
    • 1.2 中间键的规律
  • 2.自定义中间件
    • 2.1必会
    • 2.2了解
  • 2.csrf跨站请求伪造
    • 2.1钓鱼网站
      • 1.真实的网站
    • 2.钓鱼网站
  • 3.csrf跨站请求校验
    • 3.1form表单校验
    • 3.2ajax校验
  • 4.csrf相关装饰器
    • 4.1FBV下使用
    • 4.2CBV下使用
  • 5.补充知识点
    • 1.普通写法
    • 2.学习中间键的思路

1.django中间键

django中间键是django的门户:
1.请求来的时候需要先进过中间件才能到达真正的django后端。
2.响应走的时候也需要经过中间件才能发送出去。

1.1 七层中间键

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',
]
顺序是按照配置文件中注册了的中间件从下往上依次经过。

1.2 中间键的规律

都继承 MiddlewareMixin,内部都有 process_request 方法
class SessionMiddleware(MiddlewareMixin):def process_request(self, request):···def process_response(self, request, response):class CsrfViewMiddleware(MiddlewareMixin):def process_request(self, request):···def process_view(self, request, callback, callback_args, callback_kwargs):···def process_response(self, request, response):···class AuthenticationMiddleware(MiddlewareMixin):def process_request(self, request):···

2.自定义中间件

django支持程序员自定义中间件并且暴露给程序员五个可以自定义的方法,
需要导入MiddlewareMixin模块。
from django.utils.deprecation import MiddlewareMixinprocess_request
process_response
process_view

2.1必会

process_request:
1.请求来的时候需要经过每一个中间件里面的process_request方法结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行。
2.如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件。
3.如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行而是直接原路返回(校验失败不允许访问...)。
process_request方法就是用来做全局相关的所有限制功能process_response:
1.响应走的时候需要结果每一个中间件里面的process_response方法该方法有两个额外的参数request,response只要在形参中遇到 response 就必须返回。
2.该方法必须返回一个HttpResponse对象1.默认返回的就是形参response, 如果不返回回前端就没有信息,2.你也可以自己返回自己的3.顺序是按照配置文件中注册了的中间件从下往上依次经过
如果你没有定义的话 直接跳过执行下一个。
url(r'^index/', views.index),
def index(request):return HttpResponse('index')
在app01下新建文件夹mymidd.
# mymidd/myd.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponseclass MyMiddleware1(MiddlewareMixin):def process_request(self, request):print('我是第一个自定义中间键里面的process_request方法')# return HttpResponse('sss')def process_response(self, request, response):"""request: 前端打包的数据 response:  django返回浏览器的内容"""print('我是第一个自定义中间键里面的process_reponset方法')# 1.必须 return response 'NoneType' object has no attribute 'get'# 2. return HttpResponse('xxx')  django返回浏览器的内容被替换return responseclass MyMiddleware2(MiddlewareMixin):def process_request(self, request):print('我是第二个自定义中间键里面的process_request方法')def process_response(self, request, response):print('我是第二个自定义中间键里面的process_reponset方法')return response
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',# 注册自己的中间键,注册的顺序就是运行的顺序。# 在app应用下创建路径会有提示,但是如果在项目中创建就没有提示信息,需要自己对比着书写'app01.mymidd.myd.MyMiddleware1','app01.mymidd.myd.MyMiddleware2',
]
研究:
如果在第一个process_request方法就已经返回了HttpResponse对象,
那么响应走的时候是经过所有的中间件里面的process_response还是有其他情况。
结果:
是其他情况,直接走同级别的process_reponse返回flask框架也有一个中间件但是它的规律
只要返回数据了就必须经过所有中间件里面的类似于process_reponse方法

2.2了解

process_view
路由匹配成功之后执行视图函数之前,会自动执行中间件里面的该放法,
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponseclass MyMiddleware1(MiddlewareMixin):def process_request(self, request):print('我是第一个自定义中间键里面的process_request方法')def process_response(self, request, response):print('我是第一个自定义中间键里面的process_reponset方法')return responsedef process_view(self, request, view_name, *args, **kwargs):print(request, view_name, *args, **kwargs)class MyMiddleware2(MiddlewareMixin):def process_request(self, request):print('我是第二个自定义中间键里面的process_request方法')def process_response(self, request, response):print('我是第二个自定义中间键里面的process_reponset方法')return responsedef process_view(self, request, view_name, *args, **kwargs):print(request, view_name, *args, **kwargs)
process_template_response
返回的HttpResponse对象有render属性的时候才会触发,
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponseclass MyMiddleware1(MiddlewareMixin):def process_request(self, request):print('我是第一个自定义中间键里面的process_request方法')def process_response(self, request, response):"""response:  django返回浏览器的内容只要在形参中遇到 response 就必须返回"""print('我是第一个自定义中间键里面的process_reponset方法')return responsedef process_view(self, request, view_name, *args, **kwargs):print(request, view_name, *args, **kwargs)def process_template_response(self, request, response):print('我是第一个自定义中间键里面的process_template_response')return responseclass MyMiddleware2(MiddlewareMixin):def process_request(self, request):print('我是第二个自定义中间键里面的process_request方法')def process_response(self, request, response):print('我是第二个自定义中间键里面的process_reponset方法')return responsedef process_view(self, request, view_name, *args, **kwargs):print(request, view_name, *args, **kwargs)def process_template_response(self, request, response):print('我是第一个自定义中间键里面的process_template_response')return response
需要自定义一个render函数。
def index(request):print('我是一个视图函数')obj = HttpResponse('index')def render():print('内部的render')return HttpResponse('indexxxxx')obj.render = renderreturn obj
process_exception
当视图函数中出现异常的情况下触发.
显示的就是报错的信息。
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponseclass MyMiddleware1(MiddlewareMixin):def process_request(self, request):print('我是第一个自定义中间键里面的process_request方法')def process_response(self, request, response):""":param response:  django返回浏览器的内容只要在形参中遇到 response 就必须返回"""print('我是第一个自定义中间键里面的process_reponset方法')return responsedef process_view(self, request, view_name, *args, **kwargs):print(request, view_name, *args, **kwargs)def process_template_response(self, request, response):print('我是第一个自定义中间键里面的process_template_response')return responsedef process_exception(self, request, exception):print('我是第一个自定义中间件里面的process_exepion')return print(exception)class MyMiddleware2(MiddlewareMixin):def process_request(self, request):print('我是第二个自定义中间键里面的process_request方法')def process_response(self, request, response):print('我是第二个自定义中间键里面的process_reponset方法')return responsedef process_view(self, request, view_name, *args, **kwargs):print(request, view_name, *args, **kwargs)def process_template_response(self, request, response):print('我是第一个自定义中间键里面的process_template_response')return responsedef process_exception(self, request, exception):print('我是第一个自定义中间件里面的process_exepion')return print(exception)

2.csrf跨站请求伪造

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

2.1钓鱼网站

1.真实的网站
url(r'^transfer', views.transfer)
def transfer(request):if request.method == 'POST':username = request.POST.get('username')target_user = request.POST.get('target_user')money = request.POST.get('money')print('%s 给 %s 转了 %s 元' % (username, target_user, money))return render(request, 'transfer.html')
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>钓鱼网站</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script><script src="JQuery.js"></script>
</head>
<body><h1>某正版网站</h1><form action="" method="post" ><p>username: <input type="text" name="username"> </p><p>target_user: <input type="text" name="target_user"></p><p>money: <input type="text" name="money"></p><input type="submit"></form>
</body>
</html>
127.0.0.1/transfer
username:kid
target_user: qz
money : 123
提交
kid 给 qz 转了 123 元

2.钓鱼网站

内部本质
我们在钓鱼网站的页面 针对对方账户 只给用户提供一个没有name属性的普通input框
然后我们在内部隐藏一个已经写好name和value的input框
在新建一个djamgo  端口号设置为8001
url(r'^transfer', views.transfer)
def transfer(request):if request.method == 'POST':username = request.POST.get('username')target_user = request.POST.get('target_user')money = request.POST.get('money')print('%s 给 %s 转了 %s 元' % (username, target_user, money))return render(request, 'transfer.html')

将第二个框的值进行隐藏.
<p>target_user: <input type="text"></p>
<input type="text" name="target_user" value="kid" style="display:none">
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>钓鱼网站</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script><script src="JQuery.js"></script>
</head>
<body><h1>某钓鱼网站</h1><form action="http://127.0.0.1:8000/transfer" method="post" ><p>username: <input type="text" name="username"> </p><p>target_user: <input type="text"></p><input type="text" name="target_user" value="kid" style="display:none"><p>money: <input type="text" name="money"></p></p><input type="submit"></form>
</body>
</html>

3.csrf跨站请求校验

网站在给用户提供一个具有提交数据功能页面的时候,会给这个页面加一个唯一标识(随机字符串)。
当这个页面朝后端发送post请求的时候 后端会先校验唯一标识,如果唯一标识不对直接拒绝(403 forbbiden)
如果成功则正常执行···

3.1form表单校验

将中间键 'django.middleware.csrf.CsrfViewMiddleware' 的注释取消。
jango.middleware.csrf.CsrfViewMiddleware 所有post访问需要校验csrf。
form表单,中添加上内置模板语法{% csrf_token %}内部代码
<input type="hidden" name="csrfmiddlewaretoken" value="cUUWG6lmGHFGkWeeFf0ZrI8uhb9ixtSGC37Pz2fTCZp5Fwo9jNP0GcSlaJPbnsKa">
<form action="" method="post">{% csrf_token %}<p>username:<input type="text" name="username"></p><p>target_user:<input type="text" name="target_user"></p><p>money:<input type="text" name="money"></p><input type="submit">
</form>

3.2ajax校验

// 第一种 利用标签查找获取页面上的随机字符串
{# data:{"username":'kid','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}, #}
// 第二种 利用模版语法提供的快捷书写
{# data:{"username":'kid','csrfmiddlewaretoken':'{{ csrf_token }}'}, #}
// 第三种 通用方式直接拷贝js代码并应用到自己的html页面上即可
data:{"username":'kid'}
在项目下新建static文件夹,在static文件夹下建立js文件夹
复制 jquery 到js文件夹下 新建 mysetup.js,复制下面官方给的代码。
# 为static添加路径
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')
]
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 protectionreturn (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}$.ajaxSetup({beforeSend: function (xhr, settings) {if (!csrfSafeMethod(settings.type) && !this.crossDomain) {xhr.setRequestHeader("X-CSRFToken", csrftoken);}}
});
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>钓鱼网站</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script><script src="../static/js/JQuery.js"></script><script src="../static/js/mysetup.js"></script>
</head>
<body><h1>某正版网站</h1><form action="" method="post" >{% csrf_token %}<p>username: <input type="text" name="username"> </p><p>target_user: <input type="text" name="target_user"></p><p>money: <input type="text" name="money"></p><input type="submit"></form><button id="d1">ajax请求</button><script>$('#d1').click(function () {$.ajax({url:'',type:'post',// 第一种方式//data:{'username': 'kid', 'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()},// 第二种方式 利用模板语法的快捷方式//data:{'username': 'kid', 'csrfmiddlewaretoken':'{{ csrf_token }}'},// 第三种通用方式 导入静态文件data:{'username': 'kid'},success:function () {}})})</script>
</body>
</html>

4.csrf相关装饰器

1.网站整体都不校验csrf,就单单几个视图函数需要校验。
2.网站整体都校验csrf,就单单几个视图函数不校验。

4.1FBV下使用

# django准备的两个装饰器器
from django.views.decorators.csrf import csrf_protect,csrf_exempt
csrf_protect  需要校验
csrf_exempt   忽视校验
from django.views.decorators.csrf import csrf_protect,csrf_exempt
# @csrf_exempt
# @csrf_protect
def transfer(request):if request.method == 'POST':username = request.POST.get('username')target_user = request.POST.get('target_user')money = request.POST.get('money')print('%s给%s转了%s元'%(username,target_user,money))return render(request,'transfer.html')

4.2CBV下使用

针对csrf_protect符合之前所学的装饰器的三种方法。
针对csrf_exempt只能给dispatch方法加才有效。
# 设置from表单提交的地址
<form action="/Csrf/" method="post" >
from django.views import View
from django.utils.decorators import method_decorator# @method_decorator(csrf_protect,name='post')  # 针对csrf_protect 第二种方式可以
# @method_decorator(csrf_exempt,name='post')   # 针对csrf_exempt 第二种方式不可以
@method_decorator(csrf_exempt,name='dispatch')
class MyCsrfToken(View):# @method_decorator(csrf_protect)  # 针对csrf_protect 第三种方式可以# @method_decorator(csrf_exempt)   # 针对csrf_exempt 第三种方式可以def dispatch(self, request, *args, **kwargs):return super(MyCsrfToken, self).dispatch(request,*args,**kwargs)def get(self,request):return HttpResponse('get')# @method_decorator(csrf_protect)  # 针对csrf_protect 第一种方式可以# @method_decorator(csrf_exempt)   # 针对csrf_exempt 第一种方式不可以def post(self,request):return HttpResponse('post')
在CBV注释掉csrf后
@method_decorator(csrf_protect) 在前端,form 使用
{% csrf_token %}
无法完成正确的校验。

5.补充知识点

# myfile.py
name = 'kid'
import importlibres = 'myfile'
ret = importlib.import_module(res)
print(ret)
# <module 'myfile' from 'I:\\备份\\test\\pythonProject2\\myfile.py'>
print(ret.name)  # kid
importlib.import_module(res)  === from myfile import name
以点分隔
ps:
在配置文件中都写字符串,该方法最小只能到py文件名(模块名)
发送消息的程序

1.普通写法

# notif.py
def wechat(content):print('微信通知:%s' % content)def QQ(content):print('QQ通知:%s' % content)def email(content):print('邮箱通知:%s' % content)
# start.py
from notif import *def send_all(content):wechat(content)QQ(content)email(content)if __name__ == '__main__':send_all('下班')

2.学习中间键的思路

建立一个notif文件键,在文件夹下创建三个文件。
# wechat.pyclass Email(object):def __init__(self):passdef send(self, content):print('邮箱通知:%s' % content)
# QQ.pyclass QQ(object):def __init__(self):passdef send(self, content):print('QQ通知:%s' % content)
# email.py
class Wethat(object):def __init__(self):passdef send(self, content):print('微信通知:%s' % content)
# 在项目下创建一个settings.py
NOTIFY_LIST = ['notify.wechat.Wethat','notify.QQ.QQ','notify.email.Email',
]
NOTIFY_LIST = ['notify.wechat.Wethat','notify.QQ.QQ','notify.email.Email',
]
# 在 notif文件键下  创建一个__init__.py
import settings
import importlibdef send_all(content):for path_str in settings.NOTIFY_LIST:   # 以点切割, 从右往左边割一次module_path, class_name = path_str.rsplit('.', maxsplit=1)   # 'notify.wechat'    'Wethat''# 1.利用字符串导入模块module = importlib.import_module(module_path)  # from notify import xxx# 利用反射获取类名cls = getattr(module, class_name) # 拿到类的名字 Email QQ Wechat# 生成类的对象obj = cls()# 4. 理由鸭子类型直接使用send方法obj.send(content)
# 在项目下创建启动文件start.py
import notify
# 在导入模块的时候会自动执行生成对象
notify.send_all('下班了')

48.jango09相关推荐

  1. “夸夸机器人”App来了:变身百万粉丝大V,48万人给你的帖子点赞

    来源 | mashable 译者 | Kolen 出品 | AI科技大本营(ID:rgznai100) 我在Botnet上的第一条帖子获得了48万个赞. 一款全新的社交媒体风格的应用为用户提供了生活在 ...

  2. 他们为什么选择中科大少年班?官方公布48名新生名单,有人因偶像曹原,有人只是不想经历高三...

    边策 杨净 发自 凹非寺  量子位 报道 | 公众号 QbitAI 中国最受关注的大学和"专业"? 中科大少年班,一定是绕不过去的一个. 就在新生开学季,中国科学技术大学官方也公布 ...

  3. 恭喜!中科大少年班放榜:2020年全国录取48人

    来源:合肥晚报(记者 蒋瑜香) 编辑:双一流高校 经过长达11个月的招生宣传.选拔,备受关注的2020级中科大少年班录取名单正式公布. 8月13日,记者从中国科学技术大学获悉,中科大少年班学院公布了2 ...

  4. 最新调查,48%的美国人表示不会乘坐自动驾驶汽车

    梅宁航 发自 凹非寺  量子位 报道 | 公众号 QbitAI 自动驾驶发展是真的难. 这种难不单单是因为技术上的困难,还有人民直观感觉上的不信任感. 近期,美国自动驾驶汽车教育协会(PAVE)最新发 ...

  5. scala报错20/08/31 23:48:40 WARN TaskSetManager: Lost task 1.0 in stage 0.0 (TID 1, 192.168.28.94, exec

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  6. 48个Python练手项目(附详细教程)

    Python 初学者在迈过安装编程环境和基本语法的门槛 ,准备大展身手的时候,可能突然就会进入迷茫期:不知道做些什么.再学些什么.然后对编程的兴趣就会慢慢消退,找不到坚持下去的理由,从而慢慢淡忘之前学 ...

  7. 推理成本降低48倍!1张GPU就能让静态图像动起来 | 格拉兹科技大学Facebook

    鱼羊 发自 凹非寺 量子位 报道 | 公众号 QbitAI 自打伯克利和谷歌联合打造的NeRF横空出世,江湖上静态图变动图的魔法就风靡开来. 不过,想要像这样依靠AI来简化3D动态效果的制作,算力开销 ...

  8. CVPR 2020 | CentripetalNet:目标检测新网络,COCO 48 % AP超现所有Anchor-free网络

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 Anchor-free目标检测新网络,在COCO上可达48 AP!性能优于CenterNet.RPDe ...

  9. LeetCode-笔记-48.旋转图像

    LeetCode-笔记-48.旋转图像 1.本人思路 通过观察发现,就是将列数组从下往上组合形成一个新数组,插入到分别的行中. 因此循环次数为matrix.size(): 因此代码思路如下: clas ...

最新文章

  1. Py之MT:Multithreaded的简介、引入、使用方法之详细攻略
  2. linux – 我怎么知道我到somaxconn有多近?
  3. linux 防火墙 限速,linux iptables限速及限制每IP连接数
  4. oracle冷备份/恢复
  5. LiveVideoStackCon2019北京参会手册
  6. 第9章matlab符号计算答案,第9章 MATLAB符号计算_MATELAB课程设计_ppt_大学课件预览_高等教育资讯网...
  7. java wsdl接口地址_java如何实现webservice中wsdlLocation访问地址的可配置化
  8. python相机标定
  9. 计算机打字练习程序,指法练习打字软件
  10. JSON-RPC是什么东西
  11. 驱动程序安装全攻略2
  12. 一根网线连接两台电脑
  13. HCNP学习笔记之OSPF协议原理及配置1-基础知识
  14. iPhone/iPad 屏幕旋屏
  15. 基于Springboot社区居民健康档案管理系统 毕业设计-附源码220940
  16. 移动通信电波传播及损耗(二)
  17. 计算机二级的Word知识点,计算机等级考试二级office基础知识点总结.doc
  18. <OS Concepts 9th> Chap 4 线程与并发
  19. java indexeddb_初探IndexedDB
  20. arcmap叠置分析_叠加分析

热门文章

  1. 《Vue》初识、摘要及入门
  2. Hustoj 配合阿里云服务器搭建OJ平台步骤
  3. 2021高考成绩23号几点可以查询,2021年广西高考成绩23号几点可以查询,今天几点出高考成绩...
  4. 在线数据库关系图工具
  5. 三、层合板的编程练习题(1)
  6. 彻底关闭谷歌浏览器自动更新方法分享 取消chrome自动更新
  7. 8840: Medical Checkup
  8. GET一个好用的机器人API接口,非常智能,比小冰还要智能,认知智能机器人接口,免费。
  9. 文件的概述类型指针及标准的输入输出
  10. 计算机打字手怎么放,手打字怎么打就是从一个从来没摸过电脑的人,而他非常想上网打字,而 爱问知识人...