day 58 cookie与session 中间件
01. cookie与session
-
目的;目的是为了保存客户端的用户状态
-
原因;HTTP协议是无状态的
-
cookie
-
保存在客户端浏览器上的键值对
-
cookie虽然是保存在客户端浏览器上的键值对
-
但是它是有服务端设置的
-
浏览器有权禁止cookie的写入
-
django操作cookie
-
前期准备
obj = HttpResponse() obj = render() obj = redirect()
-
如何设置cookie
obj.set_cookie('k','v') # 告诉浏览器设置
-
如何获取cookie
request.COOKIES.get('k') # 获取浏览器携带过来的cookie值
-
如何设置cookies超时时间
obj.set_cookie('k','v',max_age=10) # 以秒为单位 obj.set_cookie('k1','v1',expires=3) # 兼容IE浏览器
-
删除cookie(注销 推出登录)
obj.delete_cookie('k') # 使k的值为空
-
-
-
session
-
保存在服务端上的兼职对
-
session的工作机制需要依赖于cookie
-
设置session
request.session['k']='v' # 在设置之前要在数据库中创建表 # 词条命令要将数据保存到django_session中 # django默认session失效时间是14天 两周 ''' 上面这条命令发生了三件事 ''' 1.django调用内部算法产生一个随机字符串 2.在django_session添加数据(数据的k和v都是加密处理的) 随即字符串 加密之后的数据 失效时间 3.将产生的随机字符串返回给客户端浏览器 让浏览器保存 sessionid:随机字符串
-
获取session
request.session.get('k') 1.django内部会自动去请求头里面获取cookie 2.拿着sessionid所对应的随机字符串去django_sessoion表中一一比对 3.如果比对上了 会将随机字符串对应的数据获取出来 4.反向解析成明文形式,放入request.session中供程序员调用。如果没有就是一个空字典
-
设置session失效时间
request.sessin.set_expiry(value) 1.如果value是个整数,session会在些秒数后失效。 2.如果value是个datatime或timedelta,session就会在这个时间后失效。 3.如果value是0,用户关闭浏览器session就会失效。 4.如果value是None,session会依赖全局session失效策略。
-
-
token
- 加密字符串
- 不在服务端保存session值,每次都进行加密校验
02.中间件
-
django中有七个默认的中间件
'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',
-
中间件可以用来
- 全局的用户用登录校验
- 全局的用户访问频率校验
- 全局的用户权限校验。RBAC
- 只要是和全局相关的都首先想到使用中间件来完成
-
django支持自定义中间件,并暴露了5个用户自定义的方法
-
创建自定义的中间件要创建一个类,继承MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponse,render,redirect class MyMdd1(MiddlewareMixin): def process_request(self,request): print('我是第一个中间件里面的process_request方法') # return HttpResponse("我是中间件一里面的") def process_response(self,request,response): """ :param request: :param response: 就是后端返回给前端的数据 :return: """ print('我是第一个中间件里面的process_response方法') return response # return HttpResponse("我是中间件一里面的") def process_view(self,request,view_name,*args,**kwargs): print(view_name) print(args) print(kwargs) print('我是第一个中间件里面的process_view方法') # return HttpResponse("我是中间件一里面的process_view") def process_exception(self,request,exception): print('我是第一个中间件里面的process_exception') print(exception) def process_template_response(self, request, response): print('我是第一个中间件里面的奇葩方法') return response
-
process_request
- 请求来时触发,按照配置文件中从上到下的顺序依次执行内部定义的process_request
- 如果内部没有该方法,直接跳过
- 该方法一旦返回了HttpResponse对象,会从当前层的preocess_response开始往回走
-
process_response
- 响应走的时候会按照settings配置文件中从下往上的顺序 依次执行每一个中间件内部定义的process_response方法
- 该方法必须有两个形参(request,response) 并且必须返回response形参 不返回直接报错
- 该方法返回什么(HttpResponse对象) 前端就能获得什么,将原本要返回的数据替换掉
-
process_view
- 当路由匹配成功后,视图函数执行之前触发
- 如果该方法返回一个HttpResponse对象,会直接从下往上执行process_response
-
process_exception
- 当视图函数出现错误时触发,顺序为从下往上
-
processs_template_response
- 当返回对象内部含有render属性只想一个render方法时触发,从下往上执行
def mdzz(request): print('我是视图函数mdzz') def render(): return HttpResponse('你好呀 我是奇葩') obj = HttpResponse('我很好 好的像个傻逼一样') obj.render = render return obj
-