中间件

一、什么是中间件

请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models)

响应的时候也需要经过中间件才能到达web服务网关接口

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',
]

二、django中间件作用(********)

1.网站全局的身份校验,访问频率限制,权限校验。。。只要是涉及到全局的校验你都可以在中间件完成

2.django的中间件是所有web框架中做的最好的

三、中间件执行顺序

-process_request()方法,从上往下执行
1.如果返回 HttpResponse对象,那么会直接返回,不再往下执行而是跳到同级别的process_response方法,直接往回走
2.请求来的时候,会经过每个中间件里面的process_request方法(从上往下)
-process_response,从下往上执行
1.必须要将response形参返回,这个形参指代的就是要返回给前端的数据
2.响应走的时候,会依次经过每一个中间件里面的process_response方法(从下往上)

 四、自定义中间件

1.导包

from django.utils.deprecation import MiddlewareMixin

2.定义类,继承MiddlewareMixin

在app01应用中创建一个文件夹mymiddleware,再创建一个mdd.py文件

class MyMdd(MiddlewareMixin):
def process_request(self,request):
print('我是第一个中间件里面的process_request方法') def process_response(self,request,response):
print('我是第一个中间件里面的process_response方法')
return responseclass MyMdd1(MiddlewareMixin):
def process_request(self,request):
print('我是第二个中间件里面的process_request方法') def process_response(self,request,response):
print('我是第二个中间件里面的process_response方法')
return response

3.定义视图函数

def index(request):
print("view函数...")
return HttpResponse("OK")

4.在settings中MIDDLEWARE注册自定义中间件

MIDDLEWARE =[
'mymiddleware.mdd.MyMdd',
'mymiddleware.mdd.MyMdd1',
'mymiddleware.mdd.MyMdd2', ]

5.设置路由

urlpatterns = [
url(r'^index/',view.index) ]

结果

我是第一个中间件里面的process_request方法
我是第二个中间件里面的process_request方法
view函数...
我是第二个中间件里面的process_response方法
我是第一个中间件里面的process_response方法

五、中间件五个可以自定义的方法

需要掌握的方法:

1.process_request()方法    请求来的时候会走该方法

1.请求来的时候 会经过每个中间件里面的process_request方法(从上往下)
2.如果方法里面直接返回了HttpResponse对象 那么会直接返回 不再往下执行
基于该特点就可以做访问频率限制,身份校验,权限校验

2.process_response()方法   响应回去的时候会走该方法

1.必须将response形参返回 因为这个形参指代的就是要返回给前端的数据
2.响应走的时候 会依次经过每一个中间件里面的process_response方法(从下往上)

需要了解的方法:

3.process_view()

在路由匹配成功执行视图函数之前 触发

4.process_exception()

当你的视图函数报错时,就会自动执行

5.process_template_response()

当你返回的HttpResponse对象中必须包含render属性才会触发
def index(request):
print('我是index视图函数')
def render():
return HttpResponse('什么鬼玩意')
obj = HttpResponse('index')
obj.render = render
return obj

总结:

你在书写中间件的时候,只要形参中有response,你就应该顺手将其返回,这个response就是要给前端的信息。

这五种方法有哪些特点:
1.都需要继承MiddlewareMixin
2.在注册中间件的时候,在settings中写的路径不能错

CSRF——跨站请求伪造

1.什么是CSRF攻击

攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的。

比如钓鱼网站

2.CSRF攻击原理

要完成一次CSRF攻击,受害者必须依次完成两个步骤:

  1.登录受信任网站A,并在本地生成Cookie。

  2.在不登出A的情况下,访问危险网站B。

钓鱼网站例子

通过制作一个跟正儿八经的网站一模一样的页面,骗取用户输入信息 转账交易从而做手脚
转账交易的请求确确实实是发给了中国银行,账户的钱也是确确实实少了
唯一不一样的地方在于收款人账户不对
内部原理
在让用户输入对方账户的那个input上面做手脚
给这个input不设置name属性,在内部隐藏一个实现写好的name和value属性的input框
这个value的值 就是钓鱼网站受益人账号

如何区分钓鱼网站和正经网站?在正经网站返回页面的时候,在form表单中偷偷塞一个特殊的字符串,后端记下该页面对应的字符串的值,等用户发post请求来的时候,我先去校验特殊的字符串是否匹配

如何去写这个特殊的字符串呢?模版语法有一个固定的写法{% csrf_token %},必须写在form表单内

3.CSRF攻击防范

防止钓鱼网站的思路
网站会给用户访问的form表单页面 偷偷塞一个随机字符串
请求到来的时候 会先比对随机字符串是否一致 如果不一致 直接拒绝(403)

该随机字符串有以下特点
  1.同一个浏览器每一次访问都不一样
  2.不同浏览器绝对不会重复

4.CSRF在Django中的应用

1.在form表单中使用

<form action="" method="post">
{% csrf_token %}
<p>username:<input type="text" name="username"></p>
<p>password:<input type="text" name="password"></p>
<input type="submit">
</form>

2.在ajax中使用,如何避免csrf校验

  • 有两种方法,通过修改ajax的data

  方法一:先在form表单页面上写{% csrf_token%},利用标签查找,获取到该input键值消息

data{'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}

  方法二:直接书写'{{csrf_token}}'

data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}
  • 还可以将获取随机键值对的方法,写到一个js文件中,然后导入这个文件即可

  新建一个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);
}
}
});

5.CSRF禁用

1.CSRF全局禁用

注释掉settings中MIDDLEWARE的中间件 'django.middleware.csrf.CsrfViewMiddleware',

2.CSRF局部禁用

  • 在FBV中,直接加载FBV就行了 (在页面不加csrf_token情况下)
from django.views.decorators.csrf import csrf_exempt,csrf_protect
#(前提是全局使用,没有注释csrf) 让这个不用校验,可以局部使用
#当你网站全局需要校验csrf的时候,有几个不需要校验该如何处理
@csrf_exempt
def login(request):
return HttpResponse('login') #(前提是全局禁用,注释csrf,不会进行校验) 设置就会进行校验,局部禁用
#当你网站全局不校验csrf的时候,有几个需要校验又该如何处理
@csrf_protect
def lll(request):
return HttpResponse('lll')
  • 在CBV中,只能在dispatch方法或者类上面
from django.views import View
from django.views.decorators.csrf import csrf_exempt,csrf_protect
from django.utils.decorators import method_decorator
# 这两个装饰器在给CBV装饰的时候 有一定的区别
如果是csrf_protect 那么有三种方式
# 第一种方式
# @method_decorator(csrf_protect,name='post') # 有效的
class MyView(View):
# 第三种方式
# @method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
res = super().dispatch(request, *args, **kwargs)
return res def get(self,request):
return HttpResponse('get')
# 第二种方式
# @method_decorator(csrf_protect) # 有效的
def post(self,request):
return HttpResponse('post')
如果是csrf_exempt 只有两种(只能给dispatch装) 特例
@method_decorator(csrf_exempt,name='dispatch') # 第二种可以不校验的方式
class MyView(View):
# @method_decorator(csrf_exempt) # 第一种可以不校验的方式
def dispatch(self, request, *args, **kwargs):
res = super().dispatch(request, *args, **kwargs)
return res def get(self,request):
return HttpResponse('get') def post(self,request):
return HttpResponse('post')

Django框架(十二)-- 中间件、CSRF跨站请求伪造的更多相关文章

  1. Django Ajax学习二之csrf跨站请求伪造

    方式1 $.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}' }, }); 方式2 # html文件from表单中<form& ...

  2. django上课笔记3-ORM补充-CSRF (跨站请求伪造)

    一.ORM补充 ORM操作三大难点: 正向操作反向操作连表 其它基本操作(包含F Q extra) 性能相关的操作 class UserInfo(models.Model): uid = models ...

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

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

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

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

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

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

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

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

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

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

  8. 第三百一十五节,Django框架,CSRF跨站请求伪造

    第三百一十五节,Django框架,CSRF跨站请求伪造  全局CSRF 如果要启用防止CSRF跨站请求伪造,就需要在中间件开启CSRF #中间件 MIDDLEWARE = [ 'django.midd ...

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

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

随机推荐

  1. React 引入import React 原理

    本质上来说JSX是React.createElement(component, props, ...children)方法的语法糖. 所以我们如果使用了JSX,我们其实就是在使用React,所以我们就 ...

  2. gtibase rpm包制作

    gitbase 是一个很不错的代码分析工具,我们可以直接使用sql来分析团队的代码,以下是rpm 包的制作 简单说明 rpm 包的制作使用了fpm 一个简单,方便可以跨平台的软件包制作工具 gitba ...

  3. cf1173 D. Nauuo and Circle

    链接 [cf]http://codeforces.com/contest/1175/problem/F) 思路 当1在1的位置做dp[i]为i的子树所有的方案. 一条性质是i的子树所占圆上的位置一定一 ...

  4. 【CF1042F】Leaf Sets

    [CF1042F]Leaf Sets 题面 洛谷 题解 对于一个根节点\(x\),考虑其子树内的所有\(lca\)为它的叶子节点到它的距离\(d_1<d2<...<d_m\). 那么 ...

  5. luogu P1447 [NOI2010]能量采集 欧拉反演

    题面 题目要我们求的东西可以化为: \[\sum_{i=1}^{n}\sum_{j=1}^{m}2*gcd(i,j)-1\] \[-nm+2\sum_{i=1}^{n}\sum_{j=1}^{m}gc ...

  6. Navicat自动断开连接处理方式

    问题描述 使用Navicat连接mysql后,如果一段时间不操作,那么会再次操作时会提示无响应,每次都这样确实折磨人,大大降低了工作效率! 问题解决 关闭连接→右键连接→连接属性 将上述心跳时间设置为 ...

  7. GCC编译UDF和gdb调试UDF

    Fluent版本:19.0 前面我们介绍过使用VS来编译和调试UDF,其实我们也可以用GCC来编译UDF.gdb调试UDF.本次介绍的方法更具有通用性,也适用于Linux下Fluent的UDF编译和调 ...

  8. mvn常见参数命令讲解

    关于-N -N,--non-recursive Do not recurse into sub-projects 意思是,不递归到子项目(子模块). 举例: 一个父项目下Father面有3个子项目A. ...

  9. spatiaLite

  10. 二分查找时间复杂度、partition时间复杂度

    二分查找时间复杂度 partition时间复杂度 O(n) = O(n) + O(n/2) + O(n/4)+.... 然后用等比求和公式得出是O(2n),即O(n)