Django中间件操作

django操作cookie

django操作session

CBV添加装饰器的三种方法

django中间件简介

django中间件五个常见方法

csrf跨站请求伪造

django操作cookie补充

set_signed_cookie(key,value,salt='干扰项')	# 做加盐处理

# 服务端返回给前端的cookie数据,或者客户端保存的cookie数据都有一个失效时间的,不是永久有效的,max_age就是用来管控超时时间的,超过的话就会自动清空,默认是秒数,想更改成其它单位的话,要自己去使用时间的乘法换算
set_signed_cookie(key,value,max_age=超时时间:默认是秒数)

expires:专门针对IE浏览器设置超时时间
  
HttpResponse对象.delete_cookie(key) 	# 主动注销登录,就是主动把本地保存的一些cookie删掉
eg:	在已登录的情况下
    def logout(requset):
        request.delete_cookie('name') 	#删除cookie
        return redirect('/login/')	# 让它返回到登录页面去
        
ps:学到这里要对登录操作有本质的认识:核心就是cookie的存取

django操作session

# 以后我们在使用的时候一般不是操作cookie,而是操作session,但是他们的操作方式是差不多的,cookie数据基本上是以明文为主,session数据基本是以密文为主
# 设置
request.session['key'] = value  # 可以设置多组,但是在session数据的表是保存成一行

# session的工作机制:
服务端保存用户相关状态信息 返回给客户端随机字符串,
针对保存 django需要一张表来处理 >>> 自带的django_session表
ps:django数据库迁移命令会产生一堆默认的表 其中就有一张django_session表

1.设置session内部发生的事情
  1.1.产生一个随机字符串
  1.2.表中存储随机字符串与加密数据的对应关系 
  1.3.并将产生的随机字符串也给客户端发送一份并让其保存
  	客户端保存形式:sessionid:随机字符串
把随机字符串给了客户端之后,客户端浏览器下次访问的时候就会拿着这个字符串去django_session表中去校验,校验正确的话级就可以拿到服务端存储的数据,这样就避免了客户端浏览器信息泄露
# 获取
request.session.get('key')  # 可以获取多组:
获取session内部发生的事情:
  1.1.自动获取客户端请求中的随机字符串
  1.2.自动去存储session数据的表中比对
  1.3.如果比对成功自动获取并'解密处理'
# django默认的session失效时间是14天

request.session.session_key  # 获取产生的随机字符串
request.session.delete()  # 只删客户端,就是删除当前会话的所有session数据
request.session.flush()  # 服务端 客户端都删,删除当前会话的所有session与cookie数据
request.session.set_expiry(value)  # 设置超时时间
    * 如果value是个整数,session会在些秒数后失效。
    * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    * 如果value是0,用户关闭浏览器session就会失效。
    * 如果value是None,session会依赖全局session失效策略(django默认的失效时间14天)
  
django中默认支持session,其内部提供了5种类型的session数据的存储位置 
  1.数据库存储(默认存储位置)
  2.缓存存储(类似于内存,速度快,但是不会做数据的实时同步)
  3.文件存储
  4.缓存+数据库存储
  5.动态加密

CBV添加装饰器

from django import views

class MyLoginView(views.View):
    def get(self,request):
        return HttpResponse("from CBV get view")
    def post(self,request):
        return HttpResponse('from CBV post view')
    
 如果想给CBV添加装饰器的话,不要直接装   
'''需要借助于一个专门的装饰器模块'''
from django.utils.decorators import method_decorator
# 方式1:直接在类中的某个方法上添加
class MyLoginView(views.View):
    @method_decorator(login_auth)
    def get(self, request):
        return HttpResponse("from CBV get view")
# 方式2:直接在类名上添加并指定(就是给类里面的方法添加,几个方法需要就装几个装饰器,不指定的话默认是全局)
@method_decorator(login_auth, name='get')
class MyLoginView(views.View):
    def get(self, request):
        return HttpResponse("from CBV get view")
# 方式3:重写dispatch方法并添加,作用于全局(类中所有的方法),装了之后整个CBV里面的所有方法都需要经过这个装饰器的校验 	
class MyLoginView(views.View):
    @method_decorator(login_auth)
    def dispatch(self, request, *args, **kwargs):
       return super().dispatch(request,*args,**kwargs)	# 先走这个dispatch,再走类里面的dispatch

django中间件

# 回忆django请求生命周期流程图
django中间件是django的门户 自带七个中间件 每个都有各自对应的功能

django不止有七个中间件并且每个都有很多功能和方法,只是在配置文件中提供了七种

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',	# session的相关操作
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 配置文件里面虽然是路径,但其实是一个个模块
除此之外django还支持自定义中间件并提供五个可以自定义的方法
1.  process_request
2.  process_response
3.  process_view
4.  process_template_response
5.  process_excepton

django中间件的使用场景:只要是全局相关的功能都可以在中间件中编写
  	eg:用户黑名单校验、用户访问频率校验(一种防爬措施)、网站全局用户身份校验

自定义中间件

步骤:
"""
1.在应用下创建一个任意名称的文件夹
2.在该文件夹内创建一个任意名称的py文件
3.在该py文件内编写中间件类
4.配置文件中注册
"""
# 根据django里的配置文件里面的中间件写法,可以推导出自定义中间件也是定义一个类,然后继承MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin
# 必须要掌握的方法
	1.def process_request(self,request):	# 执行视图函数之前触发
  	请求来的时候会从上往下依次执行配置文件中注册了的中间件里面的process_request方法 如果没有则直接跳过
    如果该方法自己返回了HttpResponse对象,那么请求不再继续往后直接返回相应的数据
  2.def process_response(self,requet,response):		# 先执行response请求,然后再执行视图函数,最后再返回response
    	return response		# 固定写法,必须要返回response(就是视图函数返回给客户端的数据)
  	响应走的时候会从下往上依次执行配置文件中注册了的中间件里面的process_response方法 如果没有则直接跳过
    如果该方法自己返回了HttpResponse对象,那么响应会替换成该HttpResponse对象数据 而不再是视图函数想要返回给客户端的数据
  """如果process_request返回了HttpResponse对象 那么会从当前位置从下往上执行每一个process_response"""
  
# 需要了解的方法
  1.process_view
  	路由匹配成功之后执行视图之前从上往下执行配置文件中注册了的中间件里面的process_view方法
  2.process_template_response
  	视图函数执行完毕之后返回的对象中含有render属性对应一个render方法
    则会从下往上执行配置文件中注册了的中间件里面的process_template_response方法
  3.process_exception
  	视图函数执行过程中报错并在返回响应的时候会从下往上执行配置文件中注册了的中间件里面的process_exception

csrf跨站请求伪造(中间件里面的方法)

# 前戏
	钓鱼网站:一个模仿正规网站的网址 诱骗用户在该网站上做本应该在正规网站上做的操作,从而获取到该用户在正规网站上的数据甚至是财产
  eg:假设我们需要登录网页完成转账操作
    我们不小心登录到了钓鱼网站 填写了账户 密码 对方账户等信息
    点击转账之后我们账户的钱确实减少了 但是对方账户却变成了一个你从来不认识的人
  原理:将收款人的账号 提前写成犯罪分子的然后隐藏 暴露给用户一个没有name属性的标签写着玩
# 简单模拟
	开设两个django项目 模拟两个相同的页面 ,然后将钓鱼的那个页面里的action绑定正版的那个地址,然后把value值换一下,再将端口号改一下

carf解决策略

"""针对csrf相关的校验有很多种方式 django只是提供了一些而已,仅供参考"""
服务端返回页面的时候做一些特殊标记(唯一值),客户端往服务端发送请求的时候,服务端会先验证有没有这个特殊标记,如果有就是正规网站发送的,没有就是钓鱼网站,拒绝请求。

# form表单(必须是前后端结合的,能使用模板语法的)
	<form action="" method="post">
    {% csrf_token %}	# 它会自动生成一个input标签,然后name提前写好了,value也提前写好了,然后提交之后,会把前面那些数据一并提交给后端,并且这些是隐藏的,用户看不到,后端拿到这个数据之后就会先比对这个value值是不是当初返回页面的那个value值,如果是就代表这个页面是正规的,后端同意这个请求,如果不是就拒绝这个请求
    <p>当前账户:<input type="text" name="current_user"></p>
    <p>目标账户:<input type="text" name="target_user"></p>
    <p>转账金额:<input type="text" name="money"></p>
    <input type="submit">
	</form>
# ajax请求
	1.方式1:页面任意位置先写{% csrf_token %} 之后获取数据     'csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()
  2.方式2:模板语法直接获取
    'csrfmiddlewaretoken':{{ csrf_token }}

"""通用解决方案:js脚本自动处理"""
	也只能适用于ajax提交  form表单还是需要额外指定