[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对象

  1. 默认返回的就是形参 response
  2. 你也可以自己返回自己的

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跨站请求伪造]的更多相关文章

  1. django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块

    CBV加装饰器 第一种 @method_decorator(装饰器) 加在get上 第二种 @method_decorator(login_auth,name='get') 加在类上 第三种 @met ...

  2. Web框架之Django_09 重要组件(Django中间件、csrf跨站请求伪造)

    摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于 ...

  3. Web框架之Django重要组件(Django中间件、csrf跨站请求伪造)

    Web框架之Django_09 重要组件(Django中间件.csrf跨站请求伪造)   摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是 ...

  4. csrf 跨站请求伪造相关以及django的中间件

    django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware来完成. 1.django中常用的中间件? - proces ...

  5. python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)

    一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 from app01 import views urlpatterns = [ path('admin/', admi ...

  6. Django框架(十六)-- 中间件、CSRF跨站请求伪造

    一.什么是中间件 中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出 二.中间件的作用 如果你想修改请求,例如被传送到view ...

  7. Django框架(十二)-- 中间件、CSRF跨站请求伪造

    中间件 一.什么是中间件 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models) 响应的时候也需要经过中间件才能到达web服务网关接口 djang ...

  8. Django框架(十七)—— 中间件、CSRF跨站请求伪造

    目录 中间件 一.什么是中间件 二.中间件的作用 三.中间件执行顺序 四.自定义中间件 1.导包 2.定义类,继承MiddlewareMixin 3.在视图函数中定义一个函数 4.在settings的 ...

  9. Django之CSRF 跨站请求伪造

    一.简介 1.点我了解什么是跨站请求伪造 2.django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对 ...

随机推荐

  1. Symmetry UVA - 1595

      The figure shown on the left is left-right symmetric as it is possible to fold the sheet of paper ...

  2. OO博客总结——OO落下帷幕

    OO博客总结--OO落下帷幕 凡此过往,皆为序章. 不知不觉OO课程即将落下帷幕,一路坎坎坷坷磕磕绊绊,可算是要结束了,心里终于松了一口气,也有小小的不甘和遗憾.凡此过往,皆为序章.特殊的线上OO课程 ...

  3. 分布式锁的实现之 redis 篇

    为什么需要分布式锁 引入经典的秒杀情景,100件商品供客户抢.如果是单机版的话,我们使用synchronized 或者 lock 都可以实现线程安全.但是如果多个服务器的话,synchronized ...

  4. JS笔记(二)

    1.完整的JavaScript由核心(ECMAScipt).文档对象模型(DOM).浏览器对象模型(BOM)组成. 2.<script>标签的用法:引用位置.src.async.defer ...

  5. 【SpringMVC配置失效】Springboot2.x拦截器配置不无生效

    一.环境 maven springboot版本2.x <parent> <groupId>org.springframework.boot</groupId> &l ...

  6. 缓冲区溢出分析第05课:编写通用的ShellCode

    前言 我们这次的实验所要研究的是如何编写通用的ShellCode.可能大家会有疑惑,我们上次所编写的ShellCode已经能够很好地完成任务,哪里不通用了呢?其实这就是因为我们上次所编写的ShellC ...

  7. poj2112 二分最大流+Floyd

    题意:      一个农场主有一些奶牛,和一些机器,每台机器有自己的服务上限,就是一天最多能给多少头奶牛挤奶,给你任意两点的距离,问你让所有的奶牛都被挤奶时,奶牛于机器最远距离的最近是多少. 思路: ...

  8. <JVM下篇:性能监控与调优篇>补充:使用OQL语言查询对象信息

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  9. FreeSql之Expression表达式拼接参数扩展

    在FreeSql源码中Expression表达式拼接默认最多支持到5个泛型参数,当我们使用表关联比较多的时候,就需要进行扩展. 新建一个类,将命名空间改为System.Linq.Expressions ...

  10. @NotNull 、@NotBlank、@NotEmpty区别

    @NotNull: 主要用在基本数据类型上(Integer.Double...) 不能为null,但可以为empty 举例: @NotNull(message = "标题不能为空" ...