django中间件
Django中间件简介
Django 中间件是修改 Django request 或者 response 对象的钩子,可以理解为是介于 HttpRequest 与 HttpResponse 处理之间的一道处理过程。
浏览器从请求到响应的过程中,Django 需要通过很多中间件来处理,可以看如下图所示:

Django 中间件作用:
- 修改请求,即传送到 view 中的 HttpRequest 对象。
- 修改响应,即 view 返回的 HttpResponse 对象。
自定义中间键
① 在项目名或者应用名下创建一个任意名称的文件夹
② 在该文件夹内创建一个任意名称的py文件
③ 在该py文件内需要书写类(这个类必须继承MiddlewareMixin)
在该文件下就可以定义方法了
④ 需要将类的路径以字符串的形式注册到配置文件中才能生效
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', '你自己写的中间件的路径2', '你自己写的中间件的路径3', ]
在py文件中
from django.utils.deprecation import MiddlewareMixin
class SessionMiddleware(MiddlewareMixin): def process_request(self, request): session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME) request.session = self.SessionStore(session_key) def process_response(self, request, response): return response class CsrfViewMiddleware(MiddlewareMixin): def process_request(self, request): csrf_token = self._get_token(request) if csrf_token is not None: # Use same token next time. request.META['CSRF_COOKIE'] = csrf_token def process_view(self, request, callback, callback_args, callback_kwargs): return self._accept(request) def process_response(self, request, response): return response class AuthenticationMiddleware(MiddlewareMixin): def process_request(self, request): request.user = SimpleLazyObject(lambda: get_user(request))
process_request 1.请求来的时候需要经过每一个中间件里面的process_request方法 结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行 2.如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件 3.如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行 而是直接原路返回(校验失败不允许访问...) process_request方法就是用来做全局相关的所有限制功能 process_response 1.响应走的时候需要结果每一个中间件里面的process_response方法 该方法有两个额外的参数request,response 2.该方法必须返回一个HttpResponse对象 1.默认返回的就是形参response 2.你也可以自己返回自己的 3.顺序是按照配置文件中注册了的中间件从下往上依次经过 如果你没有定义的话 直接跳过执行下一个 process_view 路由匹配成功之后执行视图函数之前,会自动执行中间件里面的该放法 顺序是按照配置文件中注册的中间件从上往下的顺序依次执行 process_template_response 返回的HttpResponse对象有render属性的时候才会触发 顺序是按照配置文件中注册了的中间件从下往上依次经过 process_exception 当视图函数中出现异常的情况下触发 顺序是按照配置文件中注册了的中间件从下往上依次经过
csrf校验
form表单
<form action="" method="post"> {% csrf_token %} <p>username:<input type="text" name="username"></p> <p>target_user:<input type="text" name="target_user"></p> <p>money:<input type="text" name="money"></p> <input type="submit"> </form>
ajax
// 第一种 利用标签查找获取页面上的随机字符串 {#data:{"username":'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()},#} // 第二种 利用模版语法提供的快捷书写 {#data:{"username":'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#} // 第三种 通用方式直接拷贝js代码并应用到自己的html页面上即可 data:{"username":'jason'}
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相关装饰器
FBV
from django.views.decorators.csrf import csrf_protect,csrf_exempt from django.utils.decorators import method_decorator """ csrf_protect 需要校验 针对csrf_protect符合我们之前所学的装饰器的三种玩法 csrf_exempt 忽视校验 针对csrf_exempt只能给dispatch方法加才有效 """ # @csrf_exempt # @csrf_protect def transfer(request): if request.method == 'POST': username = request.POST.get('username') target_user = request.POST.get('target_user') money = request.POST.get('money') print('%s给%s转了%s元'%(username,target_user,money)) return render(request,'transfer.html')
CBV
cbv在csrf中只能将装饰器装在dispatch方法上,以下两种方式其实是同一种方式
from django.views import View # 方式1 @method_decorator(csrf_exempt,name='dispatch') class MyCsrfToken(View): def get(self,request): return HttpResponse('get') def post(self,request): return HttpResponse('post') # 方式2 class MyCsrfToken(View):
@method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(MyCsrfToken, self).dispatch(request,*args,**kwargs) def get(self,request): return HttpResponse('get') def post(self,request): return HttpResponse('post')

浙公网安备 33010602011771号