中间件前端
1、什么是中间件web
请求的时候须要先通过中间件才能到达django后端(urls,views,templates,models)ajax
响应的时候也须要通过中间件才能到达web服务网关接口django
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', ]
2、django中间件做用(********)浏览器
1.网站全局的身份校验,访问频率限制,权限校验。。。只要是涉及到全局的校验你均可以在中间件完成服务器
2.django的中间件是全部web框架中作的最好的cookie
3、中间件执行顺序session
-process_request()方法,从上往下执行 1.若是返回 HttpResponse对象,那么会直接返回,再也不往下执行而是跳到同级别的process_response方法,直接往回走 2.请求来的时候,会通过每一个中间件里面的process_request方法(从上往下) -process_response,从下往上执行 1.必需要将response形参返回,这个形参指代的就是要返回给前端的数据 2.响应走的时候,会依次通过每个中间件里面的process_response方法(从下往上)
4、自定义中间件app
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方法
5、中间件五个能够自定义的方法
须要掌握的方法:
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的值 就是钓鱼网站受益人帐号
如何去写这个特殊的字符串呢?模版语法有一个固定的写法{% 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校验
方法一:先在form表单页面上写{% csrf_token%},利用标签查找,获取到该input键值消息
data{'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}
方法二:直接书写'{{csrf_token}}'
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}
新建一个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局部禁用
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')
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')