cookie和session
面前常用作登录的两种方式:
- 加盐的cookie 数据都保存在客户的浏览器上,服务端没有什么压力
- Cookie + Session 数据都保存在服务端,服务端会有一定的数据压力
一、cookie
1.cookie的由来:
HTTP协议是无状态的。
无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。
一句有意思的话来描述就是人生只如初见,对服务器来说,每次的请求都是全新的。
状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。
也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
简单来说:Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
二、cookie的应用场景
cookie在实际应用中主要有以下几种场景:1.用户登录
2.七天免登录
3.记住用户的浏览习惯
4.简单的请求限制(eg:投票)
三、Django中cookie的设置
1.不加盐的cookie:
设置cookie:(注意相应对象的设置)
rep = HttpResponse("OK") rep.set_cookie("k1","v1",max_age=10) return rep
获取cookie:
request.COOKIES("k1") request.COOKIES.get("k1",None)
2.加盐的cookie:
设置cookie:(响应对象的设置)
rep = redirect("/index/") rep.set_signed_cookie("k",user,max_age=6,salt="xxxs1") return rep
获取cookie:
request.get_signed_cookie("k",None,salt="xxxs1")
3.删除cookie:
rep.delete_cookie("k") #基于相应对象
小案例:
def login(request): if request.method == "POST": user = request.POST.get("user") psd = request.POST.get("psd") if user == 'alex' and psd == '123456': #登录成功 #从网址中获取要跳转回的页面网址 next_url = request.GET.get("next")#网址里面的参数只能从request.GET里面得到 if next_url: rep = redirect(next_url) #网址里面的参数只能从request.GET里面得到 else: rep = redirect("/index/") rep.set_signed_cookie("k",user,max_age=6,salt="xxxs1") return rep return render(request,'login.html') def index(request): cookie_k =request.get_signed_cookie("k",None,salt="xxxs1") if cookie_k: #表示已登录的用户 return render(request,"index.html") else: #去登陆 return redirect("/login/") return render(request,"index.html")
退出cookie:
def logout(request): rep = redirect("/login/") rep.delete_cookie("k") return rep
案例2(带有装饰器修复)可抓取浏览器地址进行跳转的cookie登录页面
from django.shortcuts import render,redirect,HttpResponse from functools import wraps # Create your views here. def wrapper(func): @wraps(func) def inner(request,*args,**kwargs): cookie_k = request.get_signed_cookie("k", None, salt="sisi") if cookie_k: ret = func(request,*args,**kwargs) return ret else: next_url = request.get_full_path() return redirect("/login/?next={}".format(next_url)) return inner def login(request): if request.method == "POST": user = request.POST.get("user") psd = request.POST.get("psd") if user == "alex" and psd == "123456": next_url = request.GET.get("next") if next_url: rep = redirect(next_url) else: rep = redirect('/index/') rep.set_signed_cookie("k",user,salt="sisi") return rep return render(request,"login.html") def index(request): cookie_k = request.get_signed_cookie("k", None, salt="sisi") if cookie_k: return render(request,"index.html") else: return redirect("/login/") @wrapper def home(request): return render(request,"home.html")
四、session
1.session的由来:
Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session。
基于HTTP协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的Cookie就起到桥接的作用。
我们可以给每个客户端的Cookie分配一个唯一的id,这样用户在访问时,通过Cookie,服务器就知道来的人是“谁”。然后我们再根据不同的Cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。
总结而言:Cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”;但是Cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过Cookie识别不同的用户,对应的在Session里保存私密的信息以及超过4096字节的文本。
另外,上述所说的Cookie和Session其实是共通性的东西,不限于语言和框架。
2.session的原理:
1.当用户访问服务端时,服务端生成一个字随机符串。
2.当用户登录成功后,把SessionId随机字符窜组成键值对,加到cookie里发给用户。(回给浏览器,写到cookie)
3.服务器以发送给客户端cookie中的随机字符串做键,用户信息做值,保存用户信息。(自己保留一份,作为一个key,存到一个地方,key后面对应额一个保存用户相关信息的键值对。)
详解图