目录
第六章、Cookies和Session
一、来源
由于 http 协议是无状态的,无法记录用户状态,为了能够记录用户状态,就出现了 cookie 和 session (cookie 安全性不足才出现的 session)来识别并保存用户状态
二、cookie工作原理
cookie就是保存在客户端浏览器上的键值对
工作原理:
- 当你登录成功之后,浏览器上会保存一些信息,下次再访问的时候,就会带着这些信息去访问服务端,服务端通过这些信息来识别出你的身份
查看cookie的方式
三、session的工作原理
session 是保存在服务端的键值对
工作原理:
- 服务端返回给浏览器一个随机的字符串,浏览器以键值对的形式保存(sessionid:随机字符串)
- 浏览器在访问服务端的时候,就会将这个随机字符串携带上,后端获取随机字符串与后端的记录作对比(随机字符串1:数据1)
四、如何操作cookie
服务端常见的cookie操作
#设置cookie利用的就是HttpResponse对象
obj1.set_cookie('k1','v1')
#获取cookie
request.COOKIES.get('k1')
#删除cookie
obj1.delete_cookie("k1")
#设置超时时间
max_age=None, 超时时间
五、案例
思考:
既然几个网页都需要做登录验证那么我们直接用装饰器
*装饰器参数:request, *args, **kwargs (request 如果用位置参数接取不是很方便,直接当做第一个参数好取一些)
跳转到login 登录通过后如何回到上一次未访问的地址(拼接在login/?next=上一次未访问的地址)
from functools import wraps def login_auth(func): @wraps(func) def inner(request,*args,**kwargs): if request.COOKIES.get('name'): res = func(request,*args,**kwargs) return res else: target_url = request.path_info return redirect('/login/?next=%s'%target_url) return inner
科普:
Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。写一个decorator的时候,最好在实现之前加上functools的wrap,它能保留原有函数的名称和docstring
print(request.path)和print(request.get_full_path())的区别
request.path只拿url不拿get请求携带的额外的参数,本案例只拿了127.0.0.1:8000/login/的url
request.get_full_path()啥都拿
@login_auth def home(request): # 校验用户是否登录 # if request.COOKIES.get('name'): # return HttpResponse('我是主页 只有登录了才能看') # return redirect('/login/') # 上面三行代码是不引入装饰器的原始方法 return HttpResponse('我是主页 只有登录了才能看')
六、如何操作session
设置session
request.session['key'] = value # 仅仅只会在内存产生一个缓存
1.django内部自动生成了随机的字符串
2.在django_session表中存入数据
session_key session_data date
随机字符串1 数据1 ...
随机字符串2 数据2 ...
随机字符串3 数据3 ...
3.将产生的随机字符串发送给浏览器 让浏览器保存到cookie中
sessionid:随机字符串
获取session
request.session.get('key')
1.浏览器发送cookie到django后端之后 django会自动获取到cookie值
2.拿着随机字符串去django_session表中比对 是否有对应的数据
3.如果比对上了 就讲随机字符串所对应的数据 取出赋值给request.session
如果对不上 那么request.session就是个空
说明: django session表是针对浏览器的 不同的浏览器来 才会有不同的记录
删除session
request.session.delete() # 只删除服务端的session
request.session.flush() # 浏览器和服务端全部删除
session也可以设置超时时间
request.session.set_expiry(value多种配置)
数字
0
不写
时间格式