赞
踩
是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变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.middleware.security.SecurityMiddleware
做了一些安全处理的中间件。比如设置XSS防御的请求头,比如做了http协议转为https协议的工作等。
django.contrib.sessions.middleware.SessionMiddleware
session中间件。会给request添加一个处理好的session对象。
django.middleware.common.CommonMiddleware
通用中间件,会处理一些URL,比如baidu.com会自动的处理成www.baidu.com。比如/blog/111会处理成/blog/111/自动加上反斜杠。
django.middleware.csrf.CsrfViewMiddleware
保护中间件,在提交表单的时候会必须加入csrf_token,cookie中也会生成一个名叫csrftoken的值,也会在header中加入一个HTTP_X_CSRFTOKEN的值来放置CSRF攻击。SessionMiddleware必须出现在CsrfMiddleware之前。
django.contrib.auth.middleware.AuthenticationMiddleware
用户授权中间件。会给request添加一个user对象的中间件。该中间件必须在sessionmiddleware后面。
django.contrib.messages.middleware.MessageMiddleware
消息处理中间件。为了在多个模板中可以使用我们返回给模板的变量,并且简化操作。
django.middleware.clickjacking.XFrameOptionsMiddleware
防止通过浏览器页面跨Frame出现clickjacking(欺骗点击)攻击出现。
中间件可以定义五个方法,分别是:(主要的是process_request和process_response),在自己定义中间件时,必须继承MiddlewareMixin
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)
以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户,Django的生命周期图示很明显。
from django.utils.deprecation import MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class Md1(MiddlewareMixin):
def process_request(self, request):
print("M1请求来时,效验")
def process_response(self, request, response):
print("M1返回数据时,对数据处理处理")
return response
class Md2(MiddlewareMixin):
def process_request(self, request):
print("M2效验")
# return HttpResponse("Md2中断")
def process_response(self, request, response):
print("M2返回")
return response
def index(request):
print("view函数...")
return HttpResponse("OK")
Django会在调用视图函数之前调用process_view方法。
process_view(self, request, view_func, view_args, view_kwargs)
它应该返回None或一个HttpResponse对象。 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。 如果它返回一个HttpResponse对象,Django不会调用适当的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。
这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。
process_exception(self, request, exception)
该方法对视图函数返回值有要求,必须是一个含有render方法类的对象,才会执行此方法
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
class Test:
def __init__(self, status, msg):
self.status = status
self.msg = msg
def render(self):
import json
dic = {'status': self.status, 'msg': self.msg}
return HttpResponse(json.dumps(dic))
def index(request):
print("view函数...")
return Test(True, '测试')
做IP访问频率限制
某些IP访问服务器的频率过高,进行拦截,比如限制每分钟不能超过20次。
URL访问过滤
如果用户访问的是login视图(放过)
如果访问其他视图,需要检测是不是有session认证,已经有了放行,没有返回login,这样就省得在多个视图函数上写装饰器了!
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性
可以这样来理解:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。 如下:其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户
从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:
1. 登录受信任网站A,并在本地生成Cookie。
2. 在不登出A的情况下,访问危险网站B。
目前防御 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段;在请求地址中添加 token 并验证;在 HTTP 头中自定义属性并验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="/static/jquery-3.3.1.js"></script>
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<p>用户名:<input type="text" name="name"></p>
<p>密码:<input type="text" name="password" id="pwd"></p>
<p><input type="submit"></p>
</form>
<button class="btn">点我</button>
</body>
<script>
$(".btn").click(function () {
$.ajax({
url: '',
type: 'post',
data: {
'name': $('[name="name"]').val(),
'password': $("#pwd").val(),
'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val() //这里是关键
},
success: function (data) {
console.log(data)
}
})
})
</script>
</html>
是一个字符串,可以自己用js切割,也可以用jquery的插件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/jquery.cookie.js"></script>
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<p>用户名:<input type="text" name="name"></p>
<p>密码:<input type="text" name="password" id="pwd"></p>
<p><input type="submit"></p>
</form>
<button class="btn">点我</button>
</body>
<script>
$(".btn").click(function () {
var token=$.cookie('csrftoken')
//var token='{{ csrf_token }}'
$.ajax({
url: '',
headers:{'X-CSRFToken':token},
type: 'post',
data: {
'name': $('[name="name"]').val(),
'password': $("#pwd").val(),
},
success: function (data) {
console.log(data)
}
})
})
</script>
</html>
from django.views.decorators.csrf import csrf_exempt,csrf_protect
# 不再检测,局部禁用(前提是全站使用)
# @csrf_exempt
# 检测,局部使用(前提是全站禁用)
# @csrf_protect
def csrf_token(request):#
if request.method=='POST':
print(request.POST)
return HttpResponse('ok')
return render(request,'csrf_token.html')
# CBV中使用
from django.views import View
from django.views.decorators.csrf import csrf_exempt,csrf_protect
from django.utils.decorators import method_decorator
# CBV的csrf装饰器,只能加载类上(django的bug)
# 给get方法使用csrf_token检测
@method_decorator(csrf_exempt,name='get'),#不能直接放在函数上,可以放在分发函数dispatch上不需要指定名字,是什么请求就会分发到指定的函数上
# 给post加
@method_decorator(csrf_exempt,name='post')
# 给所有方法加
@method_decorator(csrf_exempt,name='get')
class Foo(View):
def get(self,request):
pass
def post(self,request):
pass
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。