django中间件
wsgiref(django自带的web服务网关接口)
wsgiref 将浏览器发送过来的数据进行切分,在django存的数据要返回去,这个时候wsgiref就会帮你们打包返回去,打包成http协议的格式再发出去,因为我们后端处理的数据大部分都是字典的,不符合http协议数据格式
WSGI是一种协议,wsgiref,uwsgi都是基于WSGI协议实现的一个功能模块
一分钟之内来了多少次,如果一分钟来了30次,我就把你禁掉,在中间件做全局禁戒的时候是最好的选择,整个django项目都是中间件帮你把控的,全局的频率限制,访问限制都可以用中间件
七个中间件,依次经过我这七个中间件,才能达到我urls.py,返回的时候也要经过,消息的进出都要经过我的中间件,访问频率的限速,一个请求来了,可以获取到对应ip地址,在中间件里面做个session
django中间件
创一个文件夹(mymiddleware)
文件夹下创middleware文件(支持自定义中间件)
1 from django.utils.deprecation import MiddlewareMixin 2 from django.shortcuts import HttpResponse,render 3 4 class MyMiddleWare(MiddlewareMixin): #一定要继承这个类 5 def process_request(self, request): 6 print('我是第一个自定义的中间件中的process_request') 7 8 def process_response(self, request,response): 形参中存在response必须返回 9 print('我是第一个自定义的中间件中的process_response方法') 10 return response
到settings里面添加
第二个自定义中间件
1 #然后做测试 return HttpResponse 2 class MyMiddleWare(MiddlewareMixin): #一定要继承这个类 3 def process_request(self, request): 4 print('我是第一个自定义的中间件中的process_request') 5 return HttpResponse('我是第一个中间件里面返回的对象') 6 7 def process_response(self, request,response): 8 print('我是第一个自定义的中间件中的process_response方法') 9 return response
1 #然后做测试 return render (也是同级别返回) 2 class MyMiddleWare(MiddlewareMixin): #一定要继承这个类 3 def process_request(self, request): 4 print('我是第一个自定义的中间件中的process_request') 5 return render(request,'index.html') 6 7 def process_response(self, request,response): 8 print('我是第一个自定义的中间件中的process_response方法') 9 return response 10 11 结果 12 我是第一个自定义的中间件中的process_request 13 [16 / Jun / 2019 11: 12:50] "GET /index/ HTTP/1.1" 14 200 15 800 16 我是第一个自定义的中间件中的process_response方法
django自定义中间件自定义的方法
1.process_request:请求到来时会执行(必须掌握)
2.process_response:响应返回时会执行(必须掌握)
并且需要指定每一个方法什么时候触发(必须掌握)
3.process_view:路由匹配成功执行视图函数之前,会依次process_view方法
4.process_exception:视图函数中报错,会依次执行process_exception方法
5.process_template_response:视图函数必须返回render对象时才会触发process_template_response方法(了解即可)
1 class MyMiddleWare(MiddlewareMixin): #一定要继承这个类 2 def process_request(self, request): 3 print('我是第一个自定义的中间件中的process_request') 4 5 def process_response(self, request,response): 6 print('我是第一个自定义的中间件中的process_response方法') 7 return response 8 9 def process_view(self,request,view_func,view_args,view_kwargs): view_func是即将执行的视图函数名(函数地址) 10 #request是wsgiref网关接口帮你处理好的 11 print('我是第一个自定义的中间件process_view方法') 12 print(view_func.__name__) 13 14 15 class MyMiddleWare1(MiddlewareMixin): #一定要继承这个类 16 def process_request(self, request): 17 print('我是第二个自定义的中间件中的process_request') 18 19 def process_response(self, request, response): 20 print('我是第二个自定义的中间件中的process_response方法') 21 return response 22 23 def process_view(self, request, view_func, view_args, view_kwargs): 24 # request是wsgiref网关接口帮你处理好的 25 print('我是第二个自定义的中间件process_view方法') 26 print(view_func.__name__)
1 class MyMiddleWare(MiddlewareMixin): #一定要继承这个类 2 def process_request(self, request): 3 print('我是第一个自定义的中间件中的process_request') 4 5 def process_response(self, request,response): 6 print('我是第一个自定义的中间件中的process_response方法') 7 return response 8 9 def process_view(self,request,view_func,view_args,view_kwargs): 10 #request是wsgiref网关接口帮你处理好的 11 print('我是第一个自定义的中间件process_view方法') 12 print(view_func.__name__) 13 14 def process_exception(self, request,exception): 15 print('我是第一个自定义的中间件中process_exception方法') 16 print(exception) 17 18 19 class MyMiddleWare1(MiddlewareMixin): #一定要继承这个类 20 def process_request(self, request): 21 print('我是第二个自定义的中间件中的process_request') 22 23 def process_response(self, request, response): 24 print('我是第二个自定义的中间件中的process_response方法') 25 return response 26 27 def process_view(self, request, view_func, view_args, view_kwargs): 28 # request是wsgiref网关接口帮你处理好的 29 print('我是第二个自定义的中间件process_view方法') 30 print(view_func.__name__) 31 32 def process_exception(self, request, exception): 33 print('我是第二个自定义的中间件中process_exception方法') 34 print(exception)
1 class MyMiddleWare(MiddlewareMixin): #一定要继承这个类 2 def process_request(self, request): 3 print('我是第一个自定义的中间件中的process_request') 4 5 def process_response(self, request,response): 6 print('我是第一个自定义的中间件中的process_response方法') 7 return response 8 9 def process_view(self,request,view_func,view_args,view_kwargs): 10 #request是wsgiref网关接口帮你处理好的 11 print('我是第一个自定义的中间件process_view方法') 12 print(view_func.__name__) 13 14 def process_exception(self, request,exception): 15 print('我是第一个自定义的中间件中process_exception方法') 16 print(exception) 17 18 def process_template_response(self, request, response): 19 print('我是第一个自定义的中间件中process_exception方法') 20 return response 21 22 23 class MyMiddleWare1(MiddlewareMixin): #一定要继承这个类 24 def process_request(self, request): 25 print('我是第二个自定义的中间件中的process_request') 26 27 def process_response(self, request, response): 28 print('我是第二个自定义的中间件中的process_response方法') 29 return response 30 31 def process_view(self, request, view_func, view_args, view_kwargs): 32 # request是wsgiref网关接口帮你处理好的 33 print('我是第二个自定义的中间件process_view方法') 34 print(view_func.__name__) 35 36 def process_exception(self, request, exception): 37 print('我是第二个自定义的中间件中process_exception方法') 38 print(exception) 39 40 def process_template_response(self, request, response): 41 print('我是第二个自定义的中间件中process_exception方法') 42 return response
1 def index(request): 2 print('我是视图函数') 3 allala 4 return HttpResponse('我是视图函数') 5 6 7 def index(request): 8 print('app01 中的 index视图') 9 10 def render(): 11 print('in index/render') 12 return HttpResponse('098k') 13 rep= HttpResponse('ok') 14 rep.render = render() 15 return rep
总结:😜
django中间件
django中间件是类似于是django的保安
请求的时候需要先经过中间件才能到达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',
]
class SecurityMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
self.sts_seconds = settings.SECURE_HSTS_SECONDS
self.sts_include_subdomains = settings.SECURE_HSTS_INCLUDE_SUBDOMAINS
self.sts_preload = settings.SECURE_HSTS_PRELOAD
self.content_type_nosniff = settings.SECURE_CONTENT_TYPE_NOSNIFF
self.xss_filter = settings.SECURE_BROWSER_XSS_FILTER
self.redirect = settings.SECURE_SSL_REDIRECT
self.redirect_host = settings.SECURE_SSL_HOST
self.redirect_exempt = [re.compile(r) for r in settings.SECURE_REDIRECT_EXEMPT]
self.get_response = get_response
def process_request(self, request):
path = request.path.lstrip("/")
if (self.redirect and not request.is_secure() and
not any(pattern.search(path)
for pattern in self.redirect_exempt)):
host = self.redirect_host or request.get_host()
return HttpResponsePermanentRedirect(
"https://%s%s" % (host, request.get_full_path())
)
def process_response(self, request, response):
if (self.sts_seconds and request.is_secure() and
'strict-transport-security' not in response):
sts_header = "max-age=%s" % self.sts_seconds
if self.sts_include_subdomains:
sts_header = sts_header + "; includeSubDomains"
if self.sts_preload:
sts_header = sts_header + "; preload"
response["strict-transport-security"] = sts_header
if self.content_type_nosniff and 'x-content-type-options' not in response:
response["x-content-type-options"] = "nosniff"
if self.xss_filter and 'x-xss-protection' not in response:
response["x-xss-protection"] = "1; mode=block"
return response
class CsrfViewMiddleware(MiddlewareMixin):
if settings.CSRF_USE_SESSIONS:
request.session[CSRF_SESSION_KEY] = request.META['CSRF_COOKIE']
else:
response.set_cookie(
settings.CSRF_COOKIE_NAME,
request.META['CSRF_COOKIE'],
max_age=settings.CSRF_COOKIE_AGE,
domain=settings.CSRF_COOKIE_DOMAIN,
path=settings.CSRF_COOKIE_PATH,
secure=settings.CSRF_COOKIE_SECURE,
httponly=settings.CSRF_COOKIE_HTTPONLY,
)
# Set the Vary header since content varies with the CSRF cookie.
patch_vary_headers(response, ('Cookie',))
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):
if getattr(request, 'csrf_processing_done', False):
return None
# Wait until request.META["CSRF_COOKIE"] has been manipulated before
# bailing out, so that get_token still works
if getattr(callback, 'csrf_exempt', False):
return None
# Assume that anything not defined as 'safe' by RFC7231 needs protection
if request.method not in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
if getattr(request, '_dont_enforce_csrf_checks', False):
# Mechanism to turn off CSRF checks for test suite.
# It comes after the creation of CSRF cookies, so that
# everything else continues to work exactly the same
# (e.g. cookies are sent, etc.), but before any
# branches that call reject().
return self._accept(request)
if request.is_secure():
# Suppose user visits http://example.com/
# An active network attacker (man-in-the-middle, MITM) sends a
# POST form that targets https://example.com/detonate-bomb/ and
# submits it via JavaScript.
#
# The attacker will need to provide a CSRF cookie and token, but
# that's no problem for a MITM and the session-independent
# secret we're using. So the MITM can circumvent the CSRF
# protection. This is true for any HTTP connection, but anyone
# using HTTPS expects better! For this reason, for
# https://example.com/ we need additional protection that treats
# http://example.com/ as completely untrusted. Under HTTPS,
# Barth et al. found that the Referer header is missing for
# same-domain requests in only about 0.2% of cases or less, so
# we can use strict Referer checking.
referer = force_text(
request.META.get('HTTP_REFERER'),
strings_only=True,
errors='replace'
)
if referer is None:
return self._reject(request, REASON_NO_REFERER)
referer = urlparse(referer)
# Make sure we have a valid URL for Referer.
if '' in (referer.scheme, referer.netloc):
return self._reject(request, REASON_MALFORMED_REFERER)
# Ensure that our Referer is also secure.
if referer.scheme != 'https':
return self._reject(request, REASON_INSECURE_REFERER)
# If there isn't a CSRF_COOKIE_DOMAIN, require an exact match
# match on host:port. If not, obey the cookie rules (or those
# for the session cookie, if CSRF_USE_SESSIONS).
good_referer = (
settings.SESSION_COOKIE_DOMAIN
if settings.CSRF_USE_SESSIONS
else settings.CSRF_COOKIE_DOMAIN
)
if good_referer is not None:
server_port = request.get_port()
if server_port not in ('443', '80'):
good_referer = '%s:%s' % (good_referer, server_port)
else:
# request.get_host() includes the port.
good_referer = request.get_host()
# Here we generate a list of all acceptable HTTP referers,
# including the current host since that has been validated
# upstream.
good_hosts = list(settings.CSRF_TRUSTED_ORIGINS)
good_hosts.append(good_referer)
if not any(is_same_domain(referer.netloc, host) for host in good_hosts):
reason = REASON_BAD_REFERER % referer.geturl()
return self._reject(request, reason)
csrf_token = request.META.get('CSRF_COOKIE')
if csrf_token is None:
# No CSRF cookie. For POST requests, we insist on a CSRF cookie,
# and in this way we can avoid all CSRF attacks, including login
# CSRF.
return self._reject(request, REASON_NO_CSRF_COOKIE)
# Check non-cookie token for match.
request_csrf_token = ""
if request.method == "POST":
try:
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
except IOError:
# Handle a broken connection before we've completed reading
# the POST data. process_view shouldn't raise any
# exceptions, so we'll ignore and serve the user a 403
# (assuming they're still listening, which they probably
# aren't because of the error).
pass
if request_csrf_token == "":
# Fall back to X-CSRFToken, to make things easier for AJAX,
# and possible for PUT/DELETE.
request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')
request_csrf_token = _sanitize_token(request_csrf_token)
if not _compare_salted_tokens(request_csrf_token, csrf_token):
return self._reject(request, REASON_BAD_TOKEN)
return self._accept(request)
def process_response(self, request, response):
if not getattr(request, 'csrf_cookie_needs_reset', False):
if getattr(response, 'csrf_cookie_set', False):
return response
if not request.META.get("CSRF_COOKIE_USED", False):
return response
# Set the CSRF cookie even if it's already set, so we renew
# the expiry timer.
self._set_token(request, response)
response.csrf_cookie_set = True
return response
class AuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
assert hasattr(request, 'session'), (
"The Django authentication middleware requires session middleware "
"to be installed. Edit your MIDDLEWARE%s setting to insert "
"'django.contrib.sessions.middleware.SessionMiddleware' before "
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
) % ("_CLASSES" if settings.MIDDLEWARE is None else "")
request.user = SimpleLazyObject(lambda: get_user(request))
django中间件中有五个用户可以自定义的方法
django中间件可以用来做什么(***********************)
1.网站全局的身份校验,访问频率限制,权限校验...只要是涉及到全局的校验你都可以在中间件中完成
2.django的中间件是所有web框架中 做的最好的
需要我们掌握的方法有
1.process_request()方法
规律
1.请求来的时候 会经过每个中间件里面的process_request方法(从上往下)
2.如果方法里面直接返回了HttpResponse对象 那么会直接返回 不再往下执行
基于该特点就可以做访问频率限制,身份校验,权限校验
2.process_response()方法
规律
1.必须将response形参返回 因为这个形参指代的就是要返回给前端的数据
2.响应走的时候 会依次经过每一个中间件里面的process_response方法(从下往上)
需要了解的方法
3.process_view()
1.在路由匹配成功执行视图函数之前 触发
4.process_exception()
1.当你的视图函数报错时 就会自动执行
5.process_template_response()
1.当你返回的HttpResponse对象中必须包含render属性才会触发
def index(request):
print('我是index视图函数')
def render():
return HttpResponse('什么鬼玩意')
obj = HttpResponse('index')
obj.render = render
return obj
总结:你在书写中间件的时候 只要形参中有repsonse 你就顺手将其返回 这个reponse就是要给前端的消息
如何自定义我们自己的中间件,研究这上面五个方法都有哪些特点
1.如果你想让你写的中间件生效 就必须要先继承MiddlewareMixin
2.在注册自定义中间件的时候 一定要确保路径不要写错