Django之中间件与CSRF_TOKEN

news2024/9/23 15:24:21

文章目录

  • 一、什么是中间件
  • 二、中间件有什么用
  • 三、Django自定义中间件
    • 中间件中主要方法及作用
    • `创建自定义中间件的步骤:`
    • process_request与process_response方法
    • process_view方法
    • process_exception
    • process_template_response(不常用)
  • 四、CSRF_TOKEN

流程图介绍中间件
在这里插入图片描述

一、什么是中间件

Django中间件类似于django的门户,所有的请求来和响应走走必须经过中间件

中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能

Django官方中间件的定义:

	Middleware is a framework of hooks into Django’s request/response processing. 
	It’s a light, low-level “plugin” system for globally altering Django’s input or output.

中间件它的执行位置在web服务网关接口之后,在路由匹配之前执行的

二、中间件有什么用

如果你想修改请求,例如被传送到view中的HttpRequest对象。 或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现。

可能你还想在view执行之前做一些操作,这种情况就可以用 middleware来实现。

Django默认的中间件:(在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下)

	'django中自带的有七个中间件'
	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.django.middleware.security.SecurityMiddleware

做了一些安全处理的中间件。比如设置XSS防御的请求头,比如做了http协议转为https协议的工作等。

2.django.contrib.sessions.middleware.SessionMiddleware

session中间件。会给request添加一个处理好的session对象。

3.django.middleware.common.CommonMiddleware

通用中间件,会处理一些URL,比如baidu.com会自动的处理成www.baidu.com。

4.django.middleware.csrf.CsrfViewMiddleware

保护中间件,在提交表单的时候必须加入csrf_token,cookie中也会生成一个名叫csrftoken的值,也会在header中加入一个HTTP_X_CSRFTOKEN的值来放置CSRF攻击。SessionMiddleware必须出现在CsrfMiddleware之前。

5.django.contrib.auth.middleware.AuthenticationMiddleware

用户授权中间件。会给reqeust添加一个user对象的中间件。该中间件必须在sessionmiddleware后面。

6.django.contrib.messages.middleware.MessageMiddleware

消息处理中间件。为了在多个模版中可以使用我们返回给模版的变量,并且简化操作。

7.django.middleware.clickjacking.XFrameOptionsMiddleware

防止通过浏览器页面跨Frame出现clickjacking(欺骗点击)攻击出现。

中间件的执行顺序
在这里插入图片描述

每一个中间件在请求来的时候或者响应的时候都具有一定的作用。


三、Django自定义中间件

Django给我们提供了创建自定义中间件的方式,通过创建自定义中间件来实现全局的功能,例如全局用户黑名单校验、全局用户访问频率校验、网站全局用户身份校验等等。

中间件中主要方法及作用

	'中间件类必须继承自django.utils.deprecation.MiddlewareMixin类'
	
	process_request(self,request)
	用途:过滤请求
	'''
	1.请求来的时候会按照配置文件中注册了的中间件,从上往下依次执行每一个中间件里面的porcess_request方法,如果没有则直接跳过
	2.该方法如果返回了HttpResponse对象,那么请求不会再往后执行,原路返回
	'''
	
	process_view(self, request, callback, callback_args, callback_kwargs)
	用途:用于代码层面的替换和过滤,这个方法可以拿到视图函数的参数
	'''当路由匹配成功之后,执行视图函数之前,自动触发'''
	
	process_template_response(self,request,response)
	'''当视图函数返回的数据对象中含有render属性对应render函数才会触发'''
	
	process_exception(self, request, exception)
	用途:用于一般用于捕获发生的异常,并将其邮件发送给开发人员
	'''当视图函数报错之后,自动触发'''
	
	process_response(self, request, response)
	'''
	1.响应走的时候会按照配置文件中注册了的中间件,从下往上依次执行每一个中间件里面的process_response方法,如果没有则直接跳过
	2.该方法有两个形参request和response,并且默认情况下应该返回response
	3.该方法也可以自己返回HttpResponse对象,相当于狸猫换太子
	'''
'如果请求的过程中process_request方法直接返回了HttpResponse对象那么会原地执行同级别process_response返回后直接返回(flask则不同)'

创建自定义中间件的步骤:

	1.在项目名下或者任意的应用名下创建一个文件夹
	2.在该文件夹内创建一个任意名称的py文件
	3.在该py文件中编写一个自定义的中间件类,并且必须继承MiddlewareMixin
	4.紧接着去settings配置文件中注册中间件

process_request与process_response方法

当用户发起请求的时候会依次执行经过的所有中间件,这个时候的请求首先进入process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。

我们要自己定义中间件的话,需要写一个类,并且继承MiddlewareMixin

	from django.utils.deprecation import MiddlewareMixin

第一步:需要建立一个py文件夹来编写我们自定义的中间件,建议在应用层下面创建。
app-------》Middleware-----》middle.py

	from django.utils.deprecation import MiddlewareMixin

	class MyMiddleware1(MiddlewareMixin):
	    def process_request(self,request):
	        print('这是第一个中间件的process_request')
	
	    def process_response(self,request,response):  # 响应
	        print('这是第一个中间件的process_response')
	        return response
	
	
	class MyMiddleware2(MiddlewareMixin):
	    def process_request(self,request):
	        print('这是第二个中间件的process_request')
	
	    def process_response(self,request,response):  # 响应
	        print('这是第二个中间件的process_response')
	        return response

第二步:在settings.py文件里面加入我们自定义的中间件

	MIDDLEWARE = [
		# settings这个列表中存储的其实就是一个个中间件的路径
	    '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.Middleware.middle.MyMiddleware1',
	    'app.Middleware.middle.MyMiddleware2',
	]

第三步:定义视图函数

	'记得别忘记配置路由'
	def func(request):
	    print('from func')
	    return HttpResponse('from func')

当我们浏览器朝服务端发送请求,必定会经过我们刚才定义的中间件
在这里插入图片描述

process_request方法的request则是请求,response则是视图函数返回的内容到了中间件里面,然后由中间件return出去。所以我们是可以在process_response里面不写return视图函数返回的内容,自己定义内容返回。


从下图看,正常的情况下按照绿色的路线进行执行,假设中间件1有返回值,则按照红色的路线走,直接执行该类下的process_response方法返回,后面的其他中间件就不会执行。
在这里插入图片描述

也就是说中间件的process_request方法使用了return,那么其后面的中间件将不再执行,直接执行该中间件和其上面中间件的process_response方法,最终将某个process_request里面的return值返回给请求者。

由此总结:

  • 中间件的process_request方法是在执行视图函数之前执行的。
  • 当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。
  • 不同中间件之间传递的request都是同一个对象

多个中间件中的process_response方法是按照MIDDLEWARE中的注册顺序倒序执行的,也就是说第一个中间件的process_request方法首先执行,而它的process_response方法最后执行,最后一个中间件的process_request方法最后一个执行,它的process_response方法是最先执行的。


process_view方法

该方法格式:process_view(request, view_func, view_args, view_kwargs)

process_view方法的四个参数:

  • request:HTTPRequest对象
  • view_func:Django即将调用的视图函数
  • view_args:将传递给视图的位置参数的元组
  • view_kwargs:是将传递给视图的关键字参数的字典

view_args和view_kwargs都不包含第一个视图函数(request)

process_view方法是在视图函数之前,process_request方法之后执行的。

它应该返回None或一个HttpResponse对象,如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。如果它返回一个HttpResponse对象,Django不会调用适当的视图函数。它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。

自定义中间件:

	记得需要注册自定义中间件
	from django.utils.deprecation import MiddlewareMixin
	class Md1(MiddlewareMixin):
	    def process_request(self,request):
	        print('M1请求来时,校验')
	
	    def process_response(self,reqeust,response):
	        print('M1返回数据时,对数据进行处理')
	        return response
	
	    def process_view(self,request,view_func,view_args,view_kwargs):
	        print('我在只给你view函数前执行!')

	class Md2(MiddlewareMixin):
	    def process_reqeust(self,request):
	        print('M2请求来时,校验')
	
	    def process_response(self,request,response):
	        print('M2返回数据时,对数据进行处理')
	        return response
	
	    def process_view(self,request,view_func,view_args,view_kwargs):
	        pass

	执行结果》》》》:
		M1请求来时,校验
		我在只给你view函数前执行!
		from func
		M2返回数据时,对数据进行处理
		M1返回数据时,对数据进行处理

下图分析上面代码的执行过程:
在这里插入图片描述

当最后一个中间件的process_reqeust到达路由关系映射之后,返回到中间件1的process_view,然后依次往下,到达views函数,最后通过process_response依次返回到达用户。

注意:process_view如果有返回值,会越过其他的process_view以及视图函数,但是所有的process_response都还会执行。


process_exception

process_exception(self, request, exception)

该方法两个参数:

  • 一个HttpRequest对象
  • 一个exception是视图函数异常产生的Exception对象。

这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。

视图函数制造错误

	def index(request):
    print('index视图函数执行了')
    lis = [1,2,3]
    lis[4]

自定义中间件:

	class Md1(MiddlewareMixin):
	    def process_request(self,request):
	        print("Md1请求")
	        
	    def process_response(self,request,response):
	        print("Md1返回")
	        return response
	
	    def process_view(self, request, callback, callback_args, callback_kwargs):
	
	        print("md1 process_view...")
	
	    def process_exception(self,request,exception):
	        print("md1 process_exception...")


	class Md2(MiddlewareMixin):
	    def process_request(self,request):
	        print("Md2请求")
	
	    def process_response(self,request,response):
	        print("Md2返回")
	        print(response.content)
	        return response
	
	    def process_view(self, request, view_func, view_args, view_kwargs):
	        print("md2 process_view...")
	
	    def process_exception(self, request, exception):
	        print("md2 process_exception...")
	        return HttpResponse(exception)


		执行结果》》》》:
			Md1请求
			Md2请求
			md1 process_view...
			md2 process_view...
			index视图函数执行了
			md2 process_exception...
			Md2返回
			b'list index out of range'
			Md1返回

当process_exception进行return HttpResponse后,process_response方法就会拿到其返回的数据。

当views出现错误时流程图如下:
在这里插入图片描述

process_template_response(不常用)

该方法对视图函数返回值有要求,必须是一个含有render方法类的对象,才会执行此方法。

process_template_response 函数是在视图函数执行完后立即执行的

视图

	def index(request):
	    print("这里是 index 页面")
	    repsponse = HttpResponse("这里是主页面 index")
	
	    def render():
	        print("这里是 index 函数里的 render 方法")
	        return HttpResponse("index")
	
	    repsponse.render = render
	    return repsponse

自定义中间件

	class Md2(MiddlewareMixin):
	    def process_request(self,request):
	        print("Md2请求")
	
	    def process_response(self,request,response):
	        print("Md2返回")
	        return response
	
	    def process_view(self, request, view_func, view_args, view_kwargs):
	        print(view_func)
	        print("md2 process_view...")
	
	    def process_template_response(self, request, response):
	        print("视图函数执行完毕,且返回了render")
	        return response
		
		
		执行结果》》》》:
			Md2请求
			md2 process_view...
			这里是 index 页面
			视图函数执行完毕,且返回了render
			这里是 index 函数里的 render 方法
			Md2返回

四、CSRF_TOKEN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1244441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Django DRF序列化器serializer

以下案例由浅到深&#xff0c;逐步深入&#xff0c;通过实例介绍了序列化器的使用方法&#xff0c;和遇到的常见问题的解决方法。 一、序列化器serializers.Serializer 1、urls.py urlpatterns [path("api/<str:version>/depart/",views.DepartView.as_vie…

找论文找论文

这里写目录标题 找到的&#xff0c;待筛选识别检测 OCR综述&#xff0c;经典论文综述OCR识别OCR检测端到端文本识别问题集怎么看一篇论文有没有代码怎么直接找比如某一年的CVPR关于OCR方面的最新论文拿到一篇论文&#xff0c;根据论文名字怎么检索到期刊和发表日期 功能技巧找顶…

geoserver发布tif矢量数据图层

cesium加载上传至geoserver的tif矢量数据_cesium加载tiff-CSDN博客 geoserver安装及跨域问题解决方案&#xff1a;geoserver安装及跨域问题解决方案_geoserver 跨域_1 1王的博客-CSDN博客 将TIF上传至geoserver 启动geoserver服务&#xff0c;并进入geoserver主页。 1. 新建…

内建组件和模块

讨论 Vue.js 中几个非常重要的内建组件和模块&#xff0c;例如 KeepAlive 组件、Teleport 组件、Transition 组件等&#xff0c;它们都需要渲染器级别的底层支持。另外&#xff0c;这些内建组件所带来的能力&#xff0c;对开发者而言非常重要且实用&#xff0c;理解它们的工作原…

windows版本的grafana如何离线安装插件

本文以安装clickhouse的插件为例&#xff0c;记录下如何离线安装插件 1 下载插件 ClickHouse plugin for Grafana | Grafana Labs 2 找到grafana的配置文件 打开编辑&#xff0c;搜索plugin关键字&#xff0c;修改plugin的加载目录 目录不存在&#xff0c;手动创建&#xff0…

TableStructureRec: 表格结构识别推理库来了

目录 引言lineless_table_rec: 无线表格识别库安装使用结果 wired_table_rec&#xff1a;有线表格识别库安装使用结果 写在最后 引言 TableStructureRec 仓库是用来对文档中表格做结构化识别的推理库&#xff0c;包括来自 PaddleOCR 的表格结构识别算法模型、来自阿里读光有线…

创建maven的web项目

&#xff08;一&#xff09;创建maven的web项目 Step1、创建一个普通的maven项目 &#xff08;1&#xff09;新建一个empty project&#xff0c;命名为SSM2。 点击项目名&#xff0c;右键new&#xff0c;选择Module&#xff0c;左侧选择“Maven archetype”&#xff0c;可以给…

gmapping仿真

文章目录 获取源码安装依赖项编译简单场景运行gmapping开启键盘控制通过launch文件来启动gmappingGmapping建图的参数设置地图的保存和加载参考 获取源码 cd ~/catkin_ws/src/ git clone https://gitcode.com/weixin_42990464/wpr_simulation.git git clone https://gitcode.c…

Action!录屏工具免费完整版,录屏软件,打开即可解锁最新完整可用版本,支持GPU加速HDR视频录制和播放

一、软件简介 本次带来的录屏工具已升级为【完整版本】&#xff0c;所有功能全部可用。该录屏工具支持GPU硬件加速&#xff0c;可以智能识别主流硬件设备&#xff0c;支持通过GPU进行HDR视频录制和播放进行。视频录制帧率最高支持360FPS&#xff0c;直播视频帧率最高支持60FPS…

Thread类常用成员方法

点击链接返回标题-> Java线程的学习-CSDN博客 目录 前言 有关线程名字的成员方法&#xff1a; String getName() void setName(String name) Thread(String name) 获取线程对象的成员方法&#xff1a; static Thread currentThread() 让线程睡眠的成员方法&#xff1…

穿山甲SDK 集成·android接入广告·app流量变现

接入穿山甲SDK的app 数独训练APP 广告接入示例: Android 个人开发者如何接入广告SDK&#xff0c;实现app流量变现 接入穿山甲SDK app示例&#xff1a; android 数独小游戏 经典数独休闲益智 随着移动互联网的快速发展&#xff0c;广告成为了许多应用开发者获取收益的主要方…

java--static的应用知识:单例设计模式

1.什么是设计模式(Design pattern) ①一个问题通常有n中解法&#xff0c;其中肯定有一种解法最优的&#xff0c;这个最优的解法被人总结出来了&#xff0c;称之为设计模式。 ②设计模式有20多种&#xff0c;对应20多种软件开发中会遇到的问题。 2.单例设计模式 确保一个类只…

Python-Django的“日志功能-日志模块(logging模块)-日志输出”的功能详解

01-综述 可以使用Python内置的logging模块来实现Django项目的日志记录。 所以与其说这篇文章在讲Django的“日志功能-日志模块-日志输出”&#xff0c;不如说是在讲Pthon的“日志功能-日志模块-日志输出”&#xff0c;即Python的logging模块。 下面用一个实例来进行讲解。 …

PubLayNet:电子文档元素识别的有史以来最大数据集

文章目录 摘要引言相关工作文档布局的自动标注布局类别标注算法PMCOA XML预处理和解析PMCOA PDF解析字符串预处理PDF-XML匹配算法生成实例分割质量控制 数据划分 结果基于深度学习的文档分布识别表格检测微调用于不同的领域 讨论结论附录论文中的一些英文单词论文中的其他一些专…

微信小程序汽车租赁系统

微信小程序汽车租赁系统 本系统包含了3类用户&#xff0c;分别为客户、员工以及管理员&#xff0c;客户主要是满足自身的租车需求&#xff0c;员工主要负责车辆的调度问题和维修状况&#xff0c;管理员则是主要对人员、车辆和订单的管理。以下是对各自功能的详细介绍: 客户可…

MySQL的Redo Log跟Binlog

文章目录 概要Redo Log日志Redo Log的作用Redo Log的写入机制 Binlog日志Binlog的作用Binlog写入机制 两段提交 概要 Redo Log和Binlog是MySQL日志系统中非常重要的两种机制&#xff0c;也有很多相似之处&#xff0c;本文主要介绍两者细节和区别。 Redo Log日志 Redo Log的作…

ELK企业级日志分析平台——logstash

部署 新建一台虚拟机elk4部署logstash [rootelk4 ~]# yum install -y jdk-11.0.15_linux-x64_bin.rpm[rootelk4 ~]# yum install -y logstash-7.6.1.rpm 命令方式 [rootelk4 bin]# /usr/share/logstash/bin/logstash -e input { stdin { } } output { stdout {} } elasticsearc…

vivado产生报告阅读分析17-时序报告13

CDC 拓扑结构的简化板级原理图 以下部分展示了 CDC 拓扑结构的简化板级原理图以及简要说明。在所有板级原理图中 &#xff0c; 源时钟信号线 &#xff08; 通常为 clk_a&#xff09; 以蓝色高亮 &#xff0c; 目标时钟信号线 &#xff08; 通常为 clk_b &#xff09; 以橙色…

深度强化学习中的动作屏蔽(Action Masking)

RLlib中的example有一个代码是action_masking&#xff0c;很感兴趣&#xff0c;所以学习了一下 主要功能是&#xff1a; “动作屏蔽”允许代理根据当前观察选择动作。这在许多实际场景中非常有用&#xff0c;在这些场景中&#xff0c;不同的时间步长可以执行不同的操作。解释动…

解决:Gitee + PicGo配置图床失败

解决&#xff1a;Gitee PicGo配置图床失败 PicGo安装插件的时候选择&#xff1a;gitee-uploader&#xff0c;不要选择gitee&#xff01; 在Gitee新建的图床仓库中设置一个images文件夹&#xff0c;用来保存上传的图片&#xff0c;但是要注意在PicGo中的path中要写上路径/img…