""" django中间件是django的门户 1.请求来的时候须要先通过中间件才能到达真正的django后端 2.响应走的时候最后也须要通过中间件才能发送出去 django自带七个中间件 """ django请求生命周期流程图 研究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 SessionMiddleware(MiddlewareMixin): def process_request(self, request): session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME) request.session = self.SessionStore(session_key) def process_response(self, request, response): return response class CsrfViewMiddleware(MiddlewareMixin): 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): return self._accept(request) def process_response(self, request, response): return response class AuthenticationMiddleware(MiddlewareMixin): def process_request(self, request): request.user = SimpleLazyObject(lambda: get_user(request)) """ django支持程序员自定义中间件而且暴露给程序员五个能够自定义的方法 1.必须掌握 process_request process_response 2.了解便可 process_view process_template_response process_exception """
""" 1.在项目名或者应用名下建立一个任意名称的文件夹 2.在该文件夹内建立一个任意名称的py文件 3.在该py文件内须要书写类(这个类必须继承MiddlewareMixin) 而后在这个类里面就能够自定义五个方法了 (这五个方法并非所有都须要书写,用几个写几个) 4.须要将类的路径以字符串的形式注册到配置文件中才能生效 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', '你本身写的中间件的路径1', '你本身写的中间件的路径2', '你本身写的中间件的路径3', ] """ """ 1.必须掌握 process_request 1.请求来的时候须要通过每个中间件里面的process_request方法 结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行 2.若是中间件里面没有定义该方法,那么直接跳过执行下一个中间件 3.若是该方法返回了HttpResponse对象,那么请求将再也不继续日后执行 而是直接原路返回(校验失败不容许访问...) process_request方法就是用来作全局相关的全部限制功能 process_response 1.响应走的时候须要结果每个中间件里面的process_response方法 该方法有两个额外的参数request,response 2.该方法必须返回一个HttpResponse对象 1.默认返回的就是形参response 2.你也能够本身返回本身的 3.顺序是按照配置文件中注册了的中间件从下往上依次通过 若是你没有定义的话 直接跳过执行下一个 研究若是在第一个process_request方法就已经返回了HttpResponse对象,那么响应走的时候是通过全部的中间件里面的process_response仍是有其余状况 是其余状况 就是会直接走同级别的process_reponse返回 flask框架也有一个中间件可是它的规律 只要返回数据了就必须通过全部中间件里面的相似于process_reponse方法 2.了解便可 process_view 路由匹配成功以后执行视图函数以前,会自动执行中间件里面的该放法 顺序是按照配置文件中注册的中间件从上往下的顺序依次执行 process_template_response 返回的HttpResponse对象有render属性的时候才会触发 顺序是按照配置文件中注册了的中间件从下往上依次通过 process_exception 当视图函数中出现异常的状况下触发 顺序是按照配置文件中注册了的中间件从下往上依次通过 """
""" 钓鱼网站 我搭建一个跟正规网站如出一辙的界面(中国银行) 用户不当心进入到了咱们的网站,用户给某我的打钱 打钱的操做确确实实是提交给了中国银行的系统,用户的钱也确确实实减小了 可是惟一不一样的时候打钱的帐户不适用户想要打的帐户变成了一个莫名其妙的帐户 大学英语四六级 考以前须要学生本身网站登录缴费 内部本质 咱们在钓鱼网站的页面 针对对方帐户 只给用户提供一个没有name属性的普通input框 而后咱们在内部隐藏一个已经写好name和value的input框 如何规避上述问题 csrf跨站请求伪造校验 网站在给用户返回一个具备提交数据功能页面的时候会给这个页面加一个惟一标识 当这个页面朝后端发送post请求的时候 个人后端会先校验惟一标识,若是惟一标识不对直接拒绝(403 forbbiden)若是成功则正常执行 """
# form表单如何符合校验 <form action="" method="post"> {% csrf_token %} <p>username:<input type="text" name="username"></p> <p>target_user:<input type="text" name="target_user"></p> <p>money:<input type="text" name="money"></p> <input type="submit"> </form> # ajax如何符合校验 // 第一种 利用标签查找获取页面上的随机字符串 {#data:{"username":'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()},#} // 第二种 利用模版语法提供的快捷书写 {#data:{"username":'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#} // 第三种 通用方式直接拷贝js代码并应用到本身的html页面上便可 data:{"username":'jason'}
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); } } });
""" 1.网站总体都不校验csrf,就单单几个视图函数须要校验 2.网站总体都校验csrf,就单单几个视图函数不校验 """ from django.views.decorators.csrf import csrf_protect,csrf_exempt from django.utils.decorators import method_decorator """ csrf_protect 须要校验 针对csrf_protect符合咱们以前所学的装饰器的三种玩法 csrf_exempt 忽视校验 针对csrf_exempt只能给dispatch方法加才有效 """ # @csrf_exempt # @csrf_protect def transfer(request): if request.method == 'POST': username = request.POST.get('username') target_user = request.POST.get('target_user') money = request.POST.get('money') print('%s给%s转了%s元'%(username,target_user,money)) return render(request,'transfer.html') from django.views import View # @method_decorator(csrf_protect,name='post') # 针对csrf_protect 第二种方式能够 # @method_decorator(csrf_exempt,name='post') # 针对csrf_exempt 第二种方式不能够 @method_decorator(csrf_exempt,name='dispatch') class MyCsrfToken(View): # @method_decorator(csrf_protect) # 针对csrf_protect 第三种方式能够 # @method_decorator(csrf_exempt) # 针对csrf_exempt 第三种方式能够 def dispatch(self, request, *args, **kwargs): return super(MyCsrfToken, self).dispatch(request,*args,**kwargs) def get(self,request): return HttpResponse('get') # @method_decorator(csrf_protect) # 针对csrf_protect 第一种方式能够 # @method_decorator(csrf_exempt) # 针对csrf_exempt 第一种方式不能够 def post(self,request): return HttpResponse('post')
# 模块:importlib import importlib res = 'myfile.b' ret = importlib.import_module(res) # from myfile import b # 该方法最小只能到py文件名 print(ret)
import settings import importlib def send_all(content): for path_str in settings.NOTIFY_LIST: #'notify.email.Email' module_path,class_name = path_str.rsplit('.',maxsplit=1) # module_path = 'notify.email' class_name = 'Email' # 1 利用字符串导入模块 module = importlib.import_module(module_path) # from notify import email # 2 利用反射获取类名 cls = getattr(module,class_name) # Email、QQ、Wechat # 3 生成类的对象 obj = cls() # 4 利用鸭子类型直接调用send方法 obj.send(content)