目录
- 简介
- Cookie出现原因
- 实现原理
- Cookie操作
- cookie+session
- 总结:
简介
- 前几节的介绍中我们已经有能力制作一个登陆页面,在验证了用户名和密码的正确性后跳转到后台的页面。但是测试后也发现,如果绕过登陆页面。直接输入后台的url地址也可以直接访问的。这个显然是不合理的。其实我们缺失的就是cookie和session配合的验证。有了这个验证过程,我们就可以实现和其他网站一样必须登录才能进入后台页面了。
- 先说一下这种认证的机制。每当我们使用一款浏览器访问一个登陆页面的时候,一旦我们通过了认证。 服务器端就会发送一组 随机唯一 的字符串到浏览器端 ,这个被存储在浏览端的东西就叫 cookie 。而服务器端也会自己存储一下用户当前的状态,比如login=true,username=hahaha之类的用户信息。但是这种存储是以 字典形式存储 的,字典的唯一key就是刚才发给用户的唯一的cookie值。因为每个cookie都是唯一的,所以我们在电脑上换个浏览器再登陆同一个网站也需要再次验证。
Cookie出现原因
-
cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。 -
cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。
问题来了,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的cookie就起到桥接的作用。
我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。 -
总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。
-
另外,上述所说的cookie和session其实是共通性的东西,不限于语言和框架
实现原理
HTTP被设计为”无状态”,每次请求都处于相同的空间中。 在一次请求和下一次请求之间没有任何状态保持,我们无法根据请求的任何方面(IP地址,用户代理等)来识别来自同一人的连续请求。上图很明显的展示了Django的session与cookie的实现原理。服务器会生成两份相同的cookie字符串,一份保存在本地,一份发向请求的浏览器。浏览器将收到的cookie字符串保存下来,当下次再发请求时,会将信息与这段cookie一同发送到服务器,服务器得到这段cookie会与本地保存的那份判断是否相同,如果相同就表示用户已经登录成功,保存用户登录成功的状态。Django的session保存在数据库中的数据相当于一个大字典,key为cookie的字符串,value仍是一个字典,字典的key和value为用户设置的相关信息。这样就可以方便的存取session里面的信息。
Cookie操作
参数 | 描述 |
---|---|
max_age | cookie生效的时间,单位是秒 |
expires | 具体过期日期 |
path | 指定那个url可以访问到cookie;‘/’是所有; |
domain | (None代表当前域名):指定那个域名以及它下面的二级域名(子域名)可以访问这个cookie |
secure | 默认值为False;https安全相关 |
httponly | 默认值为False;限制只能通过http传输,JS无法在传输中获取和修改 |
---------------------------------------views.py-------------------------------------------------
def login(request):
print(request.COOKIES)
if request.method == "POST":
name = request.POST.get("name")
pwd = request.POST.get("pwd")
if name == "root" and pwd == "123456":
red = redirect("/app2/index/")
red.set_cookie("test1","cookie1") # 如果登陆成功,设置cookie值,保存登录状态
# 登录成功就将url重定向到后台的url
return red
#登录不成功或第一访问就停留在登录页面
return render(request,"login.html")
def index(request):
print(request.COOKIES.get("test1",None))
if request.COOKIES.get("test1",None) == "cookie1":
#如果有Cookie缓存,跳转登陆后的界面,否者返回到登录页面
return render(request,"index.html")
else :
return render(request,"login.html")
cookie+session
1、cookie引入session:
-
cookie看似解决了HTTP(短连接、无状态)的会话保持问题,但把全部用户数据保存在客户端,存在安全隐患,
-
于是cookie+session出现了!我们可以 把关于用户的数据保存在服务端,在客户端cookie里加一个sessionID(随机字符串),
-
基于以上原因:cook+session组合就此作古了单单使用cookie做会话保持的方式;
2、 cookie+session的工作流程 :
-
(1)、当用户来访问服务端时,服务端生成一个随机字符串;
-
(2)、当用户登录成功后 把 {sessionID :随机字符串} 组织成键值对 加到 cookie里发送给用户;
-
(3)、服务器以发送给客户端 cookie中的随机字符串做键,用户信息做值,保存用户信息;
from django.shortcuts import render, redirect, HttpResponse
# Create your views here.
def login(request):
print(request.COOKIES)
print(request.session)
if request.method == "POST":
name = request.POST.get("name")
pwd = request.POST.get("pwd")
if name == "root" and pwd == "123456":
request.session["is_login"] = True
request.session["username"] = name
return redirect("/app2/index/")
return render(request,"login.html")
def index(request):
if request.session.get("is_login"):
return render(request,"index.html")
else :
return redirect("/app2/login/")
总结:
一、操作Cookie
-
获取cookie:request.COOKIES[key]
-
设置cookie:response.set_cookie(key,value)
由于cookie保存在客户端的电脑上,所以,jquery也可以操作cookie。
$.cookie("list_pager_num", 30,{ path: '/' });
二、操作Session(session默认在服务器端保存15天)
-
获取session:request.session[key]
-
设置session:reqeust.session[key] = value
-
删除session:del request.session[key]
(这个删除其实就是把数据库的session_data更新为一个其他的值了,并没有立即删除)
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。