yaya

今天也要加油鸭!!!

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
return HttpResponse

 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__)
process_view

 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)
process_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
process_template_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
views.py

 

总结:😜

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.在注册自定义中间件的时候 一定要确保路径不要写错
posted @ 2019-06-20 03:09  Tiffany'.'  阅读(195)  评论(0编辑  收藏  举报