[Django高级之中间件、csrf跨站请求伪造]
[Django高级之中间件、csrf跨站请求伪造]
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.
-------------------------------------------------------------------------------
中间件是一个钩子到Django请求/响应处理的框架。
它是一个轻量级、低级的“插件”系统,用于全局改变Django的输入或输出。
官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。
但是由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。
说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。
中间件介绍和常用内置中间件
中间件:数据库中间件(mycat,分库分表),
服务器中间件(tomcat,nginx),
消息队列中间件(rabbitmq)
django中间件(Middleware):介于request与response处理之间的一道处理过程,在全局上改变django的输入与输出
django 内置中间件
打开Django项目的Settings.py文件,看到下图的MIDDLEWARE配置项
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', # 安全中间件
'django.contrib.sessions.middleware.SessionMiddleware', # 会话中间件:处理session
'django.middleware.common.CommonMiddleware', # 站点中间件:处理是否带斜杠的
'django.middleware.csrf.CsrfViewMiddleware', # CSRF保护中间件:跨站请求伪造的处理
'django.contrib.auth.middleware.AuthenticationMiddleware', # 认证中间件:提供用户认证服务
'django.contrib.messages.middleware.MessageMiddleware',# 消息中间件:基于cookie或者会话的消息功能
'django.middleware.clickjacking.XFrameOptionsMiddleware', # X-Frame-Options中间件:点击劫持保护
]
# SessionMiddleware源码
django.contrib.sessions.middleware.SessionMiddleware
process_request(self, request) # 请求来了会触发
process_response(self, request, response) # 请求走了会触发
MIDDLEWARE配置项是一个列表(列表是有序的),列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。
我们之前已经接触过一个csrf相关的中间件了?我们一开始把他注释掉,再提交post请求的时候,就不会被forbidden了,后来学会使用csrf_token之后就不再注释这个中间件了。
Django默认有七个中间件,但是django暴露给用户可以自定义中间件并且里面可以写五种方法
中间件可以定义五个方法,分别是:(主要的是process_request和process_response)
1.必须掌握
process_request(self,request)
process_response(self, request, response)
2.了解即可
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

自定义中间件:
中间件详情参考 ← 点击查看
自定义中间件需要在Django配置文件中告诉Django去哪找这个自定义的中间件,默认可以放在项目的对应app中,新建一个任意名称的文件夹eg:middleware,在此文件夹中新建任意名称的文件eg:my_middleware.py,然后在此文件中根据需求自定义五个方法中的任意一个或多个
ps:中间件的本质就是含有五个可以修改的内置方法的类,所以自定义的时候需要做的就是先继承一个Django提供的中间件混合的父类(MiddlewareMixin)。
在settings.py的MIDDLEWARE配置项中注册两个自定义中间件:
注意:自定义中间件必须在settings.py的MIDDLEWARE配置项中注册后才能使用
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',
'app01.middleware.MyMiddleWare', # 自定义中间件
'app01.middleware.MyMiddleWare1', # 自定义中间件
]
process_request方法:(重点)
1.请求来的时候需要经过每一个中间件里面的 process_request方法,经过的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
2.如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件
3.它的返回值可以是None,按正常流程继续走,交给下一个中间件处理,如果该方法返回了Httpresponse对象,那么请求将不再继续往后执行,而是直接原路返回(校验失败不允许访问.)
process_request方法就是用来做全局相关的所有限制功能
1 请求来了触发它,从上往下依次执行(在setting中中间件注册的位置)
def process_request(self, request):
如果返回None,就继续往下走
如果返回四件套之一,直接就回去了
2 在这里面写请求来了的一些判断
3 request.META.REMOTE_ADDR # 客户端地址
4 request.META.HTTP_USER_AGENT # 客户端类型
#自定义中间件示例
from django.utils.deprecation import MiddlewareMixin
class MyMiddleWare(MiddlewareMixin):
def process_request(self, request):
print('请求来了0000')
class MyMiddleWare1(MiddlewareMixin):
def process_request(self, request):
print('请求来了1111')
process_response方法:(重点)
1.响应走的时候需要经过每一个中间件里面的 process_response方法,该方法有两个额外的参数 request, response
2,该方法必须返回一个 HttpResponse对象
- 默认返回的就是形参 response
- 你也可以自己返回自己的
3.顺序是按照配置文件中注册了的中间件从下往上依次经过,如果你没有定义的话直接跳过执行下一个
# 导入MiddlewareMixin模块
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render, HttpResponse,redirect
# 定义中间件的类,它继承MiddlewareMixin
class MyMiddleWare(MiddlewareMixin):
def process_request(self, request):
print('请求来了0000')
# return HttpResponse('不让你来了')
def process_response(self, request, response):
print('请求走了0000')
return response # 一定要return response
# 定义中间件的类,它继承MiddlewareMixin
class MyMiddleWare1(MiddlewareMixin):
def process_request(self, request):
print('请求来了1111')
def process_response(self, request, response):
print('请求走了1111')
return response
总结:
当前端发来请求,Django会执行每个中间件中的process_request,执行顺序按照配置文件由上至下执行。
响应走的时候,Django会执行每个中间件中的 process_response方法,process_response方法是在视图函数之后执行的,执行顺序是按照配置文件中注册了的中间件从下往上依次执行

process_view、process_exception、process_template_response(了解):
process_view
路由匹配成功之后执行视图函数之前自动触发
self,request,view_name,*args,**kwargs
process_exception
当视图函数报错之后自动执行
self,request,exception
process_template_response
self,request,response
图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)

csrf跨站请求伪造
详情参考 ← 点击查看
django中处理csrf
1 中间件不要注释了
2 如果是form表单
<form action="" method="post">
# 表单中直接书写下列的语句即可
{% csrf_token %}
<p>给谁转:<input type="text" name="to_user" id="id_name"></p>
<p>转多少:<input type="text" name="money" id="id_money"></p>
<input type="submit" value="转账">
</form>
3 如果是ajax提交:两种方案
$.ajax({
url: '/transfer/',
method: 'post',
//data: {to_user: $('#id_name').val(), money: $('#id_money').val(),csrfmiddlewaretoken:$('[name="csrfmiddlewaretoken"]').val()},
# 方式1:借助于{% csrf_token %}生成的标签(不推荐)
data: {to_user: $('#id_name').val(), money: $('#id_money').val(),csrfmiddlewaretoken:'{{csrf_token}}'},
# 方式2:借助于模板语法直接获取
success: function (data) {
console.log(data)
}
})
------------------------------------------------------------
# 方式3:借助于官方提供的js文件自动获取
# js文件导入即可 代码如下: 直接复制即可!
# 放于static文件夹下的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相关装饰器
csrf_exempt 局部不校验csrf
csrf_protect 局部校验csrf
from django.views.decorators.csrf import csrf_exempt, csrf_protect
# csrf_exempt 局部不校验csrf
# csrf_protect 局部校验csrf
# @csrf_protect
# @csrf_exempt
def index(request):
if request.method == 'POST':
username = request.POST.get('username')
money = request.POST.get('money')
target_user = request.POST.get('target_user')
print('%s 给 %s 转了 %s 元钱'%(username,target_user,money))
return render(request,'index.html')
from django.utils.decorators import method_decorator
from django import views
# @method_decorator(csrf_protect,name='post') # 第二种 行
# @method_decorator(csrf_exempt,name='post') # 第二种 不行
class MyLogin(views.View):
# @method_decorator(csrf_protect) # 第三种 所有的方法都会加上该功能
@method_decorator(csrf_exempt) # 第三种 所有的方法都会加上该功能
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('from get')
# @method_decorator(csrf_protect) # 第一种 行
# @method_decorator(csrf_exempt) # 第一种 不行
def post(self,request):
return HttpResponse('from post')
"""
csrf_exempt该装饰器在CBV中只能给dispatch装才能生效
"""
[Django高级之中间件、csrf跨站请求伪造]的更多相关文章
- django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块
CBV加装饰器 第一种 @method_decorator(装饰器) 加在get上 第二种 @method_decorator(login_auth,name='get') 加在类上 第三种 @met ...
- Web框架之Django_09 重要组件(Django中间件、csrf跨站请求伪造)
摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于 ...
- Web框架之Django重要组件(Django中间件、csrf跨站请求伪造)
Web框架之Django_09 重要组件(Django中间件.csrf跨站请求伪造) 摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是 ...
- csrf 跨站请求伪造相关以及django的中间件
django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware来完成. 1.django中常用的中间件? - proces ...
- python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)
一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 from app01 import views urlpatterns = [ path('admin/', admi ...
- Django框架(十六)-- 中间件、CSRF跨站请求伪造
一.什么是中间件 中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出 二.中间件的作用 如果你想修改请求,例如被传送到view ...
- Django框架(十二)-- 中间件、CSRF跨站请求伪造
中间件 一.什么是中间件 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models) 响应的时候也需要经过中间件才能到达web服务网关接口 djang ...
- Django框架(十七)—— 中间件、CSRF跨站请求伪造
目录 中间件 一.什么是中间件 二.中间件的作用 三.中间件执行顺序 四.自定义中间件 1.导包 2.定义类,继承MiddlewareMixin 3.在视图函数中定义一个函数 4.在settings的 ...
- Django之CSRF 跨站请求伪造
一.简介 1.点我了解什么是跨站请求伪造 2.django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对 ...
随机推荐
- Day06_32_Java各种内部类
内部类 内部类都有哪些? 成员内部类 匿名内部类 静态内部类 局部内部类 成员内部类 - 成员内部类内部不能有静态声明(静态方法和静态变量) - 成员内部类可以访问外部类中所有的数据包括静态数据和实例 ...
- k8s kubernetes 集群 证书更新操作
转载自https://www.cnblogs.com/kuku0223/p/12978716.html 1. 各个证书过期时间 /etc/kubernetes/pki/apiserver.crt #1 ...
- 1037 Magic Coupon
The magic shop in Mars is offering some magic coupons. Each coupon has an integer N printed on it, m ...
- F - Lakes in Berland(BFS)
The map of Berland is a rectangle of the size n × m, which consists of cells of size 1 × 1. Each cel ...
- ASP微信服务号H5客户登陆,且获取客户授权的用户基本信息
ASP微信服务号H5客户登陆,且获取客户授权的用户基本信息是需要客户授权,下面讲解详细步骤: 第一步:客户点击登录页,自动跳转到微信服务器端获取code 第二步:用第一步获取的code去获取客户的ac ...
- boltdb的实现和改进
整个代码不是很复杂,可以从代码中理解如何实现. 特点:btree,很小巧,但实现了完整事务机制,稳定,即使丢电也不会导致数据库错误. 整个结构如下: meta page (前两页) --- > ...
- Spring Security 上
Spring Security 上 Security-dome 1.创建项目 创建一个Spring Boot项目,不用加入什么依赖 2.导入依赖 <dependencies> <!- ...
- VRRP中的上层回的路由
如图,PC1和PC2处于不同网段,他们到AR3都有两条路可以选,现在要让他们到达AR3负载均衡,并且当AR1和 AR2的其中一个路由器挂了之后,他们仍然可以正常到达AR3. 他们去往AR3的VRRP的 ...
- 一个或多个筛选器或者Listeners启动失败 的问题探索以及解决方案
2020年10月9日更新 经过本人对SSM框架理解的加深和对IDEA工具使用的熟悉,现提出一种新的解决办法,以前的解决办法可能存在问题 1. 问题描述: 使用IDEA作为开发工具,使用Maven作为项 ...
- 【vue-02】基础语法
插值操作 插值运算符 语法:{{数据}} 插值运算符可以对数据进行显示{{msg}},也可以在插值运算符中进行表达式计算{{cnt*2}}. v-html 希望以html格式进行输出 htmlData ...