标签:目录 自定义中间件 orm super util his put 获取 document
目录
mymiddleware/mdd.py 自定义中间件
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MyMdd(MiddlewareMixin):
def process_request(self, request):
print(‘我是第一个中间件里面的process_request方法‘)
def process_response(self, request, response):
print(‘我是第一个中间件里面的process_response方法‘)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print(view_func)
print(view_args)
print(view_kwargs)
print(‘我是第一个中间件里面的process_view方法‘)
def process_exception(self, request, exception):
print(‘我是第一个中间件里面的process_exception‘)
def process_template_response(self, request, response):
print(‘我是第一个中间件里面的process_template_response‘)
return response
class MyMdd1(MiddlewareMixin):
def process_request(self, request):
print(‘我是第二个中间件里面的process_request方法‘)
def process_response(self, request, response):
print(‘我是第二个中间件里面的process_response方法‘)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print(view_func)
print(view_args)
print(view_kwargs)
print(‘我是第二个中间件里面的process_view方法‘)
def process_exception(self, request, exception):
print(‘我是第二个中间件里面的process_exception‘)
def process_template_response(self, request, response):
print(‘我是第二个中间件里面的process_template_response‘)
return response
class MyMdd2(MiddlewareMixin):
def process_request(self, request):
print(‘我是第三个中间件里面的process_request方法‘)
def process_response(self, request, response):
print(‘我是第三个中间件里面的process_response方法‘)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
print(view_func)
print(view_args)
print(view_kwargs)
print(‘我是第三个中间件里面的process_view方法‘)
def process_exception(self, request, exception):
print(‘我是第三个中间件里面的process_exception‘)
def process_template_response(self, request, response):
print(‘我是第三个中间件里面的process_template_response‘)
return response
在 settings.py 中的配置
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‘,
‘mymiddleware.mdd.MyMdd‘, # 配置上
‘mymiddleware.mdd.MyMdd1‘, # 配置上
‘mymiddleware.mdd.MyMdd2‘, # 配置上]
我们可以总结一下:
请求来的时候会依次执行 settings.py 配置文件中注册了的中间件里的该方法
- 如果没有该方法则直接跳过,走下一个中间件
- 如果该方法里返回了 HttpResponse 对象,那么会直接从当前中间件的 process_response 方法 从下往上依次执行返回,不会再接着往下执行
- 执行顺序:从上往下
- 该方法可以实现对用户身份的校验,访问频率的限制,用户权限的校验...
响应走的时候会依次执行 settings.py 配置文件中注册了的中间件里的该方法(必须将 response 形参返回,因为这个 response 指代的就是返回给前端的数据)
- 如果没有该方法则直接跳过,走下一个中间件
- 执行顺序:从下往上
- 该方法可以帮你实现缓存机制(减缓服务器、数据库的压力)
路由匹配成功 执行视图函数之前 自动触发(从上往下依次执行)
当视图函数报错了,自动触发(从下往上依次执行)
视图函数返回的 HttpResponse 对象中包含了 render 属性时会触发,或者是表明一个对象时 TemplateResponse 对象或等价方法 的时候也会触发(从下往上依次执行)
def index(request):
print("我是 index 视图函数")
def render():
return HttpRespone('用户最终能够看到的结果') # ******
obj = HttpResponse('index')
obj.render = render # 返回的 HttpResponse 对象中必须包含 render 属性,才能触发中间件里定义的 process_template_response 方法
return obj
强调:在写中间件的时候,只要形参中有 response ,就要记得将其返回,这个Response 是要给前端的信息
顾名思义:可以做出钓鱼网站这种的
就类似于你搭建了一个跟银行一模一样的web页面
用户在你的网站转账的时候输入用户名 密码 对方账户
银行里面的钱确实少了 但是发现收款人变了
到底咋回事呢?
你写的form表单中 用户的用户名 密码都会真实的提交给银行后台
但是收款人的账户却不是用户填的 你暴露给用户的是一个没有name属性的input框
你自己提前写好了一个隐藏的带有name和value的input框
解决钓鱼网站的策略
只要是用户想要提交post请求的页面 我在返回给用户的时候就提前设置好一个随机字符串
当用户提交post请求的时候 我会自动先取查找是否有该随机字符串
如果有 正常提交
如果没有 直接报403
from django.views.decorators.csrf import csrf_exempt,csrf_protect,ensure_csrf_cookie
csrf_exempt # 某个视图不需要进行csrf校验
csrf_protect # 某个视图需要进行csrf校验
ensure_csrf_cookie # 确保生成csrf的cookie
只有两种装饰的方式:
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator
# 第一种
@method_decorator(csrf_exempt, name='dispatch')
class MyCsrf(View):
# 第二种
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('hahaha')
除了csrf_exempt之外,所有的其他装饰器在CBV上面都有三种方式:
@method_decorator(csrf_protect,name='post')
class MyCsrf(View):
@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request,*args,**kwargs)
def get(self,request):
return HttpResponse('hahaha')
@method_decorator(csrf_protect)
def post(self,request):
return HttpResponse('post')
这个是我的知识盲区 后续再补
目前所学的拥有post请求的方法有form
表单和ajax发送
form表单
你在写的时候只需要加上一个
{% csrf_token %}
ajax发送有三种
第一种 自己再页面上先通过{% csrf_token %}获取到随机字符串 然后利用标签查找
data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},
第二种
data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},
第三种
sataic文件夹 再创建一个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);
}
}
});
然后在html文件上加这一行就好了
{#<script src="/static/setup.js"></script>#}
这样就不需要 在 html 中写 {% csrf_token %}
或在 ajax 中写 {{ csrf_token }}
了
当你网站全局都需要校验 csrf 的时候(未注释掉 csrf 中间件时),有几个不需要校验该如何处理? @csrf_exempt
当你的网站全局不校验 csrf 的时候(注释掉 csrf 中间件时),有几个需要校验该如何处理 ?@csrf_protect
from django.views.decorators.csrf import csrf_exempt
# 全局开启时,局部禁用
@csrf_exempt
def index(request):
pass
有两种方式,不能针对单个方法,是针对全局的
# CBV比较特殊,不能单独加在某个方法上
# 只能加在类上或dispatch方法上
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
# @method_decorator(csrf_exempt,name='dispatch') # 第一种
class Csrf_Token(View):
@method_decorator(csrf_exempt) # 第二种
def dispatch(self,request,*args,**kwargs):
res = super().dispatch(request,*args,**kwargs)
return res
# @method_decorator(csrf_exempt) # 这里这么写不行!!!
def get(self,request):
pass
def post(self,request):
pass
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def lll(request):
return HttpResponse('lll')
from django.views.decorators.csrf import csrf_protect
from django.views import View
from django.utils.decorators import method_decorator
# 第一种方式
# @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')
原文借鉴了https://www.cnblogs.com/suwanbin/p/11591887.html
在这里感谢!
标签:目录 自定义中间件 orm super util his put 获取 document
原文地址:https://www.cnblogs.com/demiao/p/11768709.html