Django生命周期,中间件(MiddlewareMixin)与csrf(跨站请求伪造),XSS攻击 (跨站请求脚本攻击)
Django生命周期
浏览器 - server - 中间件 - process_request(中间件处理请求) - 路由 - process_view - 在返回中间件过滤 - process_response (中间件处理响应) - 返回Server - 返回浏览器
中间件( MiddlewareMixin )
简介
# 中间件是什么 请求和响应之间的一道屏障 # 中间件的作用 控制请求和响应
中间件的执行顺序
# process_request 请求的时候,从上往下执行
如果return HttpResponse的对象,直接返回了。如果return None 继续往下走
# process_response ,从下往上执行
必须 return HttpResponse的对象
中间件的方法
# 中间件1直接返回, HttpResponse对象,直接走自己的response
def process_request(self,request): # 请求来的时候,响应执行 def process_response(self,request,response): # 响应回去的时候,执行
def process_view(self,request,callback,callback_args,callback_kwargs): print(callback) # 视图层函数内存地址 print(callback_args) # 接受路由无名分组参数 print(callback_kwargs) # 接受路由有名分组参数 ret = callback(request) # 执行视图层函数 return ret def process_exception(self, request, exception) # 接受错误信息(了解) # 该方法对视图函数的返回值又要求,必须是一个含有render方法类的对象,才会执行此方法 [ 例如以下例子 ] def process_template_response(self, request, response) #(了解)
class Test(): def render(self): return HttpResponse('test') def test_middle(request): # 会触发render函数的执行 return Test()
自定义中间件
from django.utils.deprecation import MiddlewareMixin
class MyMiddelware(MiddlewareMixin): # 继承MiddlewareMixin类 def process_request(self,request): # 发送请求来的时候执行 print('我是Middleware ----- 1 process_request ') return None # 接着往下走
# return HttpResponse # 直接放回,不往下走 def process_response(self,request,response): # 响应回去的时候执行 print('我是Middleware ----- 1 process_response ')
# response.set_cookie('name', 'lqz') 给全局写入cookie
return response
def process_view(self,request,callback,callback_args,callback_kwargs): # 所有视图函数
print(callback) # 拿到函数
print(callback_args) # 函数位置参数
print(callback_kwargs) # 函数关键字参数
ret = callback(request) # 执行函数
return ret
def process_exception(self,request,exception):
print(exception) # 捕捉异常信息
def process_template_response(self,request,response):
return response # 该方法对视图函数的返回值又要求,必须是一个含有render方法类的对象,才会执行此方法
注册中间件
csrf (跨站请求伪造)
csrf是什么
攻击者盗用你的身份,以你的名义发送恶意请求,服务器来说这个请求是合法的
防范csrf (django用的第二中)
# 方法一:refer 验证发送请求的地址,每一次发送者的地址
# 方法二:加一个随机字符串校验(加载请求的路径里,加在请求体中)
# 方法三:在请求头中加字符串校验
# form表单提交(随机字符串放在请求体中) <form action="" method="post"> {% csrf_token %} # 添加随机字符串 {{ csrf_token }} <p>name: <input type="text" name="name"></p> <p>name: <input type="text" name="pwd"></p> <input type="submit" value="提交"> </form> # ajax提交(随机字符串放在请求体中) $("#btn").click(function () { $.ajax({ url: '/auth/', type: 'post', data: { 'name': $('[name="name"]').val(), 'pwd': $('[name="pwd"]').val(), 'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val(), # 添加随机字符串(推荐使用) //'csrfmiddlewaretoken': '{{ csrf_token }}', # 添加随机字符串 }, success: function (data) { alert(data) } }) }) # ajax 提交(随机字符串放在请求头中)[ js操作cookie ] ( 不推荐使用 ) $("#btn").click(function () { var token = $.cookie('csrftoken'); $.ajax({ url: '/auth/', headers: {'X-CSRFToken': token}, # 添加在请求头里 type: 'post', data: { 'name': $('[name="name"]').val(), 'pwd': $('[name="pwd"]').val(), }, success: function (data) { alert(data) } }) })
局部禁用( csrf_exempt )与 局部使用( csrf_protect )
装饰fbv
from django.views.decorators.csrf import csrf_exempt,csrf_protect # 装饰fbv @csrf_exempt # 局部禁用,全局使用 def func(request): return HttpResponse('ok') @csrf_protect # 局部使用,全局禁用 def func(request): return HttpResponse('ok')
装饰cbv(只能装饰在类上或者dispatch方法上)
from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator from django.views import View @method_decorator(csrf_protect,name='dispatch') # 装饰在类上 class Csrf_disable(View): # @method_decorator(csrf_protect) # 或者装饰在 dispatch 方法上 def dispatch(self, request, *args, **kwargs): ret=super().dispatch(request, *args, **kwargs) # 调用父类的dispatch方法 return ret def get(self,request): return HttpResponse('ok') def post(self,request): return HttpResponse('post---ok')
XSS攻击 (跨站请求脚本攻击)
攻击原理:程序员写一段脚本语言,恶意攻击你的网站
防范XS攻击
# 前台渲染用:safe 模板语言能解析标签
# {{ article_obj.content|safe }}
soup = BeautifulSoup(content,"html.parser") # 防xss攻击,解析标签 all_tag = soup.find_all() for i in all_tag: if i.name == "script": i.decompose() # 删除script标签
作业:
1 登录认证,写在中间件中(只有登录的请求不需要登录以后操作,其他请求,都必须登录以后操作)
2 写一个频率控制的中间件(任意用户,一分钟只能访问3次)应用上csrf
-思路:
-当前访问的ip地址取出来
-存一个临时变量{ip:[时间1,时间2,时间3]}