day55:django:cookie&session
- 2020 年 9 月 22 日
- 笔记
- PythonS31-笔记, Python全栈31期-笔记
目录
Cookie
1.Cookie前戏
HTTP协议的两个特点
1.无连接
将协议设计为请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端。
2.无状态
什么是无状态?
无状态的意思是每次请求都是独立的,
它的执行情况和结果与前面的请求和之后的请求都无直接关系,
它不会受前面的请求响应情况直接影响,
也不会直接影响后面的请求响应情况
简单的来说:无状态是指服务器不知道客户端是什么状态。
对于无状态的解释
要明白,这句话的含义是指在说明,http协议作为技术背景的web应用程序请求——应答模式是无状态的,这个事实基本不会发生改变,也不会因为加入cookies、session机制而变成有状态的。
要明白,这种前后因果关系:“我们要实现的是一种web应用,实现这种应用的协议我们选择了http这种本质上是无状态的通信协议。
但是事实上,我们需要我们的web应用是有状态的。所以我们加入了cookies、session等机制去实现有状态的web应用。
2.Cookie的引入
1.cookie的引入
因为http无状态,所以出现了cookie,cookie是一种浏览器技术
2.cookie能做什么?
1.浏览器访问服务端,带着一个空的cookie,
2.然后由服务器产生内容,浏览器收到相应后保存在本地;
3.当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。

3.cookie规范
- Cookie大小上限为4KB;
- 一个服务器最多在客户端浏览器上保存20个Cookie;
- 一个浏览器最多保存300个Cookie,因为一个浏览器可以访问多个服务器。
上面的数据只是HTTP的Cookie规范,但在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己的能力起见,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等!但也不会出现把你硬盘占满的可能!
注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。
4.cookie和HTTP头
Cookie是通过HTTP请求和响应头在客户端和服务器端传递的:
- Cookie:请求头,客户端发送给服务器端;
- 格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;
- Set-Cookie:响应头,服务器端发送给客户端;
- 格式:一个Cookie对象一个Set-Cookie: Set-Cookie: a=A Set-Cookie: b=B Set-Cookie: c=C
5.cookie的覆盖
如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个Cookie,即:a=AA。
3.django中操作cookie
cookie的获取/设置/修改/删除
1.获取cookie
# 获取cookie request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) #带签名的值 ''' 参数: default: 默认值 salt: 加密盐 max_age: 后台控制过期时间 '''
2.设置cookie
# 设置cookie '''cookie的获取都是基于request对象的''' '''cookie的设置都是基于HttpResponse对象的''' rep = HttpResponse(...) rep = render(request, ...) rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='加密盐', max_age=None, ...)
3.修改cookie
# 修改cookie ret.set_cookie('username', 'xxx') #相同的键设置不同的值就是修改
4.删除cookie
# 删除cookie ret.delete_cookie('username')
cookie参数的意义
key # 键 value='' # 值 max_age=None # 超时时间,单位为秒 5表示5秒后失效 expires=None # 超时时间(IE requires expires,so set it if hasn't been already.)值为时间日期类型数据 path='/' # Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问 domain=None # Cookie生效的域名 secure=True # https传输 httponly=False # 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
Session
1.cookie的局限性
1.cookie是明文存储的
2.cookie的大小限制
Cookie大小上限为4KB;
一个服务器最多在客户端浏览器上保存20个Cookie;
一个浏览器最多保存300个Cookie,因为一个浏览器可以访问多个服务器。
2.session技术

session比cookie的强大之处
Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取,
因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session。
cookie的桥接作用
问题来了,基于HTTP协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的Cookie就起到桥接的作用。
我们可以给每个客户端的Cookie分配一个唯一的id,这样用户在访问时,通过Cookie,服务器就知道来的人是“谁”。
然后我们再根据不同的Cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。
cookie和session各自实现的功能总结
总结而言:Cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”;
但是Cookie以文本的形式保存在本地,自身安全性较差;
所以我们就通过Cookie识别不同的用户,对应的在Session里保存私密的信息以及超过4096字节的文本。
3.django操作session
# 设置session request.session['k1'] = 123 request.session.setdefault('k1',123) # 获取session request.session['k1'] request.session.get('k1',None) # 删除session del request.session['k1'] # 清空session request.session.flush()
4.Session详细流程解析

5.session实例分析
这是一段登录的视图函数,在函数中添加两个session,在添加session时,做了三件事
def login(request): if request.method == 'GET': return render(request, 'login.html') else: uname = request.POST.get('username') if uname == 'root' or uname=='abc': request.session['is_login'] = True request.session['username'] = uname # request.session # 1 生成一个随机字符串 # 2 将随机字符串放到cookie中,名称为sessionid # 3 将设置的session数据,序列化+加密,保存到了django-session表中 return redirect('/home/') else: return redirect('/login/')
这是一段注销的视图函数,这个时候我们要删除session,在删除session时,做了两件事
def logout(requset): requset.session.flush() # 1 删除cookie中的数据 # 2 删除数据库中django-session表中的记录 return redirect('/login/')
这是一个基于session的登录认证中间件,这个时候我们要查session中某个键的值,在查session的时候,做了三件事
# 基于session的登录认证中间件 class LoginAuth(MiddlewareMixin): white_list = ['/login/', ] # 白名单 def process_request(self,request): path = request.path # 获取当前请求路径 if path not in self.white_list: # 如果路径不在白名单内 is_login = request.session.get('is_login') # 获取session中is_login的值 # request.session['is_login'] # 1 取出请求中cookie键为sessionid的值 # 2 通过这个值到django-session表中获取数据 # 3 将数据解密并且反序列化得到原来的数据 if is_login != True: return redirect('/login/')
6.对于cookie和session的总结
…
django外部脚本调用django环境
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_cookie.settings") import django django.setup() from app01 import models models.Book.objects.create( title='xxx', price=200, )


