Django Middleware 中间件

Django  Middleware 中间件

中间件字符串导入方式
settins.py -> MIDDLEWARE 中间件的放置位置

用户请求时,最先是从中间件,全部按顺序执行
中间件又有两种,接收和返回的

  1. 接收请求的中间件,request
  2. 返回请求的中间件, response

请求过来:

  1. 中间件:拦截一部分请求;比如验证session, 没有登录的 请求一些页面,跳转至登录页;(图片为中间件的请求过程.)
    2 .再到 urls ,分发请求
    3 .到views 视图 ,通过 CBV(dispatch反射) 和 FBV 的 get 请求 讲 template 页面渲染返回给用户;
  2. 渲染之前 可以从数据库拿出数据,放到render 的参数里面传递过去, locals() 表示 把所有参数传递
    还可以 实例化 其他 form 类,并渲染给前端
  • 可以应用于:
    • 请求日志
    • 用户登录认证
    • 各种跳转
    • 防火墙

自定义中间件

settins.py -> MIDDLEWARE 先去注册到里面才可以应用
django 1.11 以后
form djang.utils.deprecation import MiddlewareMixin
这个就没了,需要手动自己写到你的自定义的文件里去

settings.py

from django.middleware.common import CommonMiddleware

white_list = ['/login_demo/']   # 白名单机制, 不用验证session 信息 #中间件 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', 'md.middleware.MiddlewareLogin', # 注册 ] 

自定义的 中间件 -> middleware.py

class MiddlewareMixin(object): def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__() def __call__(self, request): response = None if hasattr(self, 'process_request'): response = self.process_request(request) if not response: response = self.get_response(request) if hasattr(self, 'process_response'): response = self.process_response(request, response) return response #自己写的中间件需要 手动去继承它 MiddlewareMixin class Middleware_hc_login(MiddlewareMixin): def process_request(self, request): print ('你需要自定义的代码,写在这') if not request.META.get('PATH_INFO') in white_list: if not request.session.get('login'): return redirect('/login') def process_response(self, response): print ('这个是你的response返回,必须最后带上return返回') print ('一般可以不写这个response,只要写request就可以了') return response 

白名单机制

white_list = ['/login']      #  如果是登录的话,这个白名单就不会判断session

if not request.META.get('PATH_INFO') in white_list: if not request.session.get('login'): return redirect('/login') 

关于请求头部信息

Header 和 request.META
request.META 是一个Python字典,包含了所有本次HTTP请求的Header信息,比如用户IP地址和用户Agent(通常是浏览器的名称和版本号)。 注意,Header信息的完整列表取决于用户所发送的Header信息和服务器端设置的Header信息。

这个字典中几个常见的键值有:

HTTP_REFERER
进站前链接网页,如果有的话。 (请注意,它是REFERRER的笔误。)

HTTP_USER_AGENT
用户浏览器的user-agent字符串,如果有的话。 例如: "Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17" .

REMOTE_ADDR
客户端IP,如:"12.345.67.89" 。(如果申请是经过代理服务器的话,那么它可能是以逗号分割的多个IP地址,如:"12.345.67.89,23.456.78.90" 。)

那么 request.META 里面还有什么有用的数据呢?动手写一个简单的view函数来显示 request.META 的所有数据,这样你就知道里面有什么了。

def display_meta(request): values = request.META.items() values.sort() html = [] for k, v in values: html.append('%s%s' % (k, v)) return HttpResponse('%s
' % '\n'.join(html))

结果如下:

ALLUSERSPROFILE C:\ProgramData
APPDATA C:\Users\l3591\AppData\Roaming
COMMONPROGRAMFILES  C:\Program Files\Common Files
COMMONPROGRAMFILES(X86) C:\Program Files (x86)\Common Files COMMONPROGRAMW6432 C:\Program Files\Common Files COMPUTERNAME HC COMSPEC C:\WINDOWS\system32\cmd.exe DJANGO_SETTINGS_MODULE hc_learning.settings DRIVERDATA C:\Windows\System32\Drivers\DriverData FPS_BROWSER_APP_PROFILE_STRING Internet Explorer FPS_BROWSER_USER_PROFILE_STRING Default HOMEDRIVE C: HOMEPATH \Users\l3591 LOCALAPPDATA C:\Users\l3591\AppData\Local LOGONSERVER \\HC NUMBER_OF_PROCESSORS 8 ONEDRIVE C:\Users\l3591\OneDrive ONLINESERVICES Online Services OS Windows_NT PATH D:\python3.7\Scripts\;D:\python3.7\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\iCLS\;C:\Program Files\Intel\Intel(R) Management Engine Components\iCLS\;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\Git\cmd;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;D:\python3\Scripts\;D:\python3\ PATHEXT .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC PLATFORMCODE KV PROCESSOR_ARCHITECTURE AMD64 PROCESSOR_IDENTIFIER Intel64 Family 6 Model 142 Stepping 10, GenuineIntel PROCESSOR_LEVEL 6 PROCESSOR_REVISION 8e0a PROGRAMDATA C:\ProgramData PROGRAMFILES C:\Program Files PROGRAMFILES(X86) C:\Program Files (x86) PROGRAMW6432 C:\Program Files PSMODULEPATH C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules PUBLIC C:\Users\Public PYCHARM D:\pycharm\PyCharm 2018.3\bin; PYCHARM_HOSTED 1 PYCHARM_MATPLOTLIB_PORT 59802 PYTHON3 D:\python3.7\python.exe PYTHONIOENCODING UTF-8 PYTHONPATH C:\Users\l3591\Desktop\hc_learning;D:\pycharm\PyCharm 2018.3\helpers\pycharm_matplotlib_backend PYTHONUNBUFFERED 1 REGIONCODE APJ SESSIONNAME Console SYSTEMDRIVE C: SYSTEMROOT C:\WINDOWS TEMP C:\Users\l3591\AppData\Local\Temp TMP C:\Users\l3591\AppData\Local\Temp USERDOMAIN HC USERDOMAIN_ROAMINGPROFILE HC USERNAME hc USERPROFILE C:\Users\l3591 WINDIR C:\WINDOWS RUN_MAIN true SERVER_NAME hc GATEWAY_INTERFACE CGI/1.1 SERVER_PORT 8000 REMOTE_HOST CONTENT_LENGTH SCRIPT_NAME SERVER_PROTOCOL HTTP/1.1 SERVER_SOFTWARE WSGIServer/0.2 REQUEST_METHOD GET PATH_INFO /meta QUERY_STRING REMOTE_ADDR 127.0.0.1 CONTENT_TYPE text/plain HTTP_HOST 127.0.0.1:8000 HTTP_CONNECTION keep-alive HTTP_CACHE_CONTROL max-age=0 HTTP_UPGRADE_INSECURE_REQUESTS 1 HTTP_USER_AGENT Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0 HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*'/'*;q=0.8 HTTP_ACCEPT_ENCODING gzip, deflate, sdch, br HTTP_ACCEPT_LANGUAGE zh-CN,zh;q=0.8 HTTP_COOKIE csrftoken=AOFQMm36wEvD2Y2TrPgnS4RhBWRo3kcic1UScGKDFZ7sUJDOQfGgBlX1HKqZY1CN wsgi.input <_io.BufferedReader name=996> wsgi.errors <_io.TextIOWrapper name='' mode='w' encoding='UTF-8'> wsgi.version (1, 0) wsgi.run_once False wsgi.url_scheme http wsgi.multithread True wsgi.multiprocess False wsgi.file_wrapper 

解析客户端IP 并判断是否存在代理

通常访问者的IP就在其中,所以我们可以用下列方法获取用户的真实IP:

#X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,
#只有在通过了HTTP 代理或者负载均衡服务器时才会添加该项。

def get_ip(request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] #所以这里是真实的ip else: ip = request.META.get('REMOTE_ADDR')#这里获得代理ip return ip

扩展


中间件运用
-权限
-用户登录验证
-django的csrf_token 如何实现
csrf_token 验证在 process_view 方法里面
检查 视图是否被 @csrf_exempt (免除csrf认证)
去请求体 或 cookie 中获取token

两种 设置的方式
一种通过 装饰器
一种通过 中间件


1. process_request # 进
2. prrcess_view # 视图
3. process_response # 出
4. process_exception # 处理异常
5. process_render_template # 如果有template方法就会返回

 

请求流程

用户 -> process_request -> url路由匹配到了,但没执行 -> 跳转回中间件开头再从头走一遍到到 -> process_request -> 再到执行的views视图执行

执行完定义的逻辑 从 process_response 出去
如果中间有异常 会直接走 process_exception 处理返回异常
如果有template 就会走 process_render_template


from django.views.decorators.csrf import csrf_exempt, csrf_protect
@csrf_protect # 需要验证csrf_token认证
@csrf_exempt # 免除csrf_token认证

 

 

转载于:https://www.cnblogs.com/huidou/p/10757904.html

你可能感兴趣的:(操作系统,python,开发工具)