cookie和session的那些事
对于经常网购的朋友来说,经常会遇到一种情况:
打开淘宝或京东商城的首页,输入个人账号和密码进行登陆,然后进行购物,支付等操作都不需要用户再次输入用户名和密码
但是如果用户换一个浏览器或者等几个小时后再刷新这些网页进行购物操作,就必须要再次输入用户名和密码了.
这是为什么呢??这就用到了cookie和session的知识了.
1. cookie的简介
1、http是无状态协议,cookie不属于http协议范围.
在实际应用中,服务端与客户端需要保持连接状态,此时就需要使用到cookie.
cookie的工作原理是:由服务器产生客户端身份信息发送给客户端,客户端收到信息后保存在本地;
当客户端浏览器再次访问服务端时,会自动带上这段身份信息,服务器通过这段信息来判断客户端的身份。
打开chrome浏览器,在地址栏里输入www.cnblogs.com
,回车在检查中可以的信息如下图所示:
其中,可以看到此次的请求头(Request Headers):
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:__gads=ID=ec125291e23201fe:T=1504664243:S=ALNI_MZTHHsRs1K2HAD8kB_Q7zN777zCMA
Host:www.cnblogs.com
If-Modified-Since:Sat, 09 Sep 2017 12:38:59 GMT
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36
在这些信息里,可以看到cookie信息是包含在请求头里的.
浏览器发请求的时候,会从浏览器中取出cookie附加到请求头上,给服务端发过去.服务端接收到客户端的cookie之后,会给客户端返回相应的信息.
还可以看到服务端的响应头(Response Headers):
Cache-Control:public, max-age=19
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=utf-8
Date:Sat, 09 Sep 2017 12:42:16 GMT
Expires:Sat, 09 Sep 2017 12:42:36 GMT
Last-Modified:Sat, 09 Sep 2017 12:42:06 GMT
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-Frame-Options:SAMEORIGIN
X-UA-Compatible:IE=10
2、cookie在一定程度上解决了"保持状态"
的需求
由于cookie本身最大支持4096字节,并且cookie保存在客户端,可能被拦截或窃取,
因此需要有一种新的东西,它来弥补cookie的一些缺陷,并且保存在服务端,有较高的安全性,这就是session。
基于http协议的无状态特征,服务器不知道访问者的身份,此时cookie就起到桥接的作用。
服务端给每个客户端的cookie分配一个唯一的随机id,用户在访问服务端时,服务器通过cookie来判断客户端的身份。
服务端根据cookie的id的不同,在一定的期限内保存客户端传送过来的账号密码等关键信息.
3、cookie弥补了http无状态的不足,让服务器能够判断客户端的身份;
cookie以文本的形式保存在本地,自身安全性较差,因此服务端通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。
4、cookie和session其实是共通性的东西,不限于语言和框架
2.cookie和session的工作机制
每当我们使用一款浏览器访问一个登陆页面的时候,一旦我们通过了认证,服务器端就会发送一组随机唯一的字符串(假设是123abc)到浏览器端.
这个被存储在浏览器端的东西就叫cookie。而服务器端也会存储一下用户当前的状态,比如login=true
,username="name"
之类的用户信息。
这种信息是以字典形式存储成为一个字符串,这串字符串以用户第一次请求时得到的cookie值为键,这就是session.
那么如果在服务器端查看session信息的话,理论上就会看到如下样子的类似的字典
{'123abc':{'login':true,'username':'hahaha'}}
因为每个cookie都是唯一随机的,所以我们在同一台电脑上换个浏览器再登陆同一个网站也需要再次验证。
那么为什么说我们只是理论上看到这样子类似的字典呢?因为处于安全性的考虑,其键和值在服务器端都会被加密。
所以我们服务器上就算打开session信息看到的也是类似与以下样子的东西:
{'123abc':dasdasdasd1231231da1231231}
3.cookie和session的初步使用
例子:制作一个登陆页面,服务端使用cookie和session验证了用户名和密码后才能跳转到后台的页面。
3.1 首先创建一个Django的项目,配置好urls和settings,templates中创建一个login.html和index.html页面
views中的代码:
def index(request):
return render(request,"index.html")
def login(request):
print("cookie:",request.COOKIES)#打印cookie信息
if request.method=="POST":#如果浏览器使用post方式提交信息
name=request.POST.get("username")
pwd=request.POST.get("password")
if name=="hello" and pwd=="123456":
return redirect("/index/")
return render(request,"login.html")
login页面:
<form action="/login/" method="post">
<p>姓名<input type="text" name="username"></p>
<p>密码<input type="password" name="password"></p>
<p><input type="submit"></p>
</form>
index页面:
<h3>welcome to index page</h3>
打开浏览器,输入http://127.0.0.1:8000/login/
打开login页面,输入正确的用户名和密码,进入index页面
此时可以在后端看到如下的cookie信息
cookie: {'csrftoken': 'AdkajMM65wOqa0NONe6dVwYqphGNDOgMbuzstmAy92HJ3GxRWUNpqXKJFXBv1Rn5',
'sessionid': '7jfj6uqbz6vylplfv429bhfdxh14iwfp'}
其中sessionid中的信息就是Django分配给浏览器的一段随机字符串.
3.2 由用户自己设置cookie信息
修改login视图函数:
def login(request):
print("cookie:",request.COOKIES)
if request.method=="POST":
name=request.POST.get("username")
pwd=request.POST.get("password")
if name=="hello" and pwd=="123456":
res=redirect("/index/")
res.set_cookie("login_message","hello python")#设置cookie信息
return res
return render(request,"login.html")
然后重启应用,重新输入用户名和密码,进入index页面,此时可以看到如下的cookie信息:
cookie: {'csrftoken': 'AdkajMM65wOqa0NONe6dVwYqphGNDOgMbuzstmAy92HJ3GxRWUNpqXKJFXBv1Rn5',
'sessionid': '7jfj6uqbz6vylplfv429bhfdxh14iwfp', 'login_message': 'hello python'}
可以看到在后端的login视图函数中设置的cookie的键值对,浏览器请求后又会被服务端接收.
用户请求页面时,是带着标示自己的身份信息的,服务端对客户端的身份信息进行判断,只有身份正确,才能进入index页面.
但是如果在浏览器的地址中直接输入index的路由地址,也能进入index的页面的情况,这不符合我们的要求.
3.3 实现客户端没有cookie,即使用户输入index路由信息,服务端发送登录页面给用户
如果客户端没有cookie,说明用户名或密码没有验证成功,服务端就会把login页面发送给客户端浏览器,
只有用户输入正确的用户名和密码,服务端才会把index页面发送给客户端浏览器.
修改index视图函数:
def index(request):
if request.COOKIES.get("login_message")=="hello python":
return render(request,"index.html",locals())
else:
return redirect("/login/")
这样用户在一个浏览器中经过验证进入index.html页面后,清除cookie或者更换一个浏览器再想进入index页面,就要再次验证用户名和密码了.
由于用户的cookie信息保存在客户端,每与服务端通信一次,客户端就要把cookie信息发送经服务端一次,而且保存在客户端也不够安全,所以又出现了session
session也保存客户端身份的信息,用户登录后服务端把表示用户身份的信息保存成以键值对形式存在的session中,然后服务端把这个字典发送给客户端的cookie,
这时客户端的cookie就以一个字符串的形式存在.
客户端使用cookie和session与服务端进行通信的步骤:
用户经过用户名和密码验证登陆后,生成一个字典,将字典存入session,session的key是自动生成一段字符串标识,也就是前面说过的cookie.
服务端返回给客户端session,session的value存储了用户的关键信息,如user和iflogin等.
在Django中用到session时,cookie由服务端随机生成,写到浏览器的cookie中,每个浏览器都有自己的cookie值,是session寻找用户信息的唯一标识
每个浏览器请求到后台接收的request,这时的session等价于标识用户身份信息的字典
3.4 使用cookie加session来完成上面的例子
修改views中的login视图函数
def login(request):
print("cookie:",request.COOKIES)
print("session:",request.session)
if request.method=="POST":
name=request.POST.get("username")
pwd=request.POST.get("password")
if name=="hello" and pwd=="123456":
res=redirect("/index/")
res.set_cookie("login_message","hello python")
return res
return render(request,"login.html")
再次刷新浏览器,输入正确的用户名和密码后,打印cookie和session:
cookie: {'csrftoken': 'AdkajMM65wOqa0NONe6dVwYqphGNDOgMbuzstmAy92HJ3GxRWUNpqXKJFXBv1Rn5',
'sessionid': '7jfj6uqbz6vylplfv429bhfdxh14iwfp', 'login_message': 'hello python'}
session: <django.contrib.sessions.backends.db.SessionStore object at 0x00000000043D7D30>
可以看到的是此时的session是一个对象.
知道了cookie和session的情况后,那么该怎么使用cookie和session呢
修改视图函数
def index(request):
if request.session.get("is_login",None):#获取session中用户登录的信息
name=request.session.get("user")#获取session中的用户名
return render(request,"index.html",locals())
else:
return redirect("/login/")
def login(request):
print("cookie:",request.COOKIES)
print("session:",request.session)
if request.method=="POST":
name=request.POST.get("username")
pwd=request.POST.get("password")
if name=="hello" and pwd=="123456":
request.session["is_login"]=True
request.session["user"]=name
return redirect("/index/")
return render(request,"login.html")
先使用
python manage.py makemigrations
python manage.py migrate
命令初始化数据库,
然后在浏览器中输入http://127.0.0.1:8000/index/
后,直接进入登录页面了,输入正确的用户名和密码,后端会打印如下信息:
cookie: {}
session: <django.contrib.sessions.backends.db.SessionStore object at 0x00000000043B46D8>
4 cookie和session的用法:
4.1 操作cookie
获取cookie request.COOKIE[key]
设置cookie response.set_cookie(key,value)
由于cookie保存在客户端的电脑上,所以jQuery也可以操作cookie
在上面的例子中,在html页面中就使用Django的语法可以渲染name变量.
设置cookie的失效时间:
import datetime#导入datetime模块
response.set_cookie("username",{"11":"22"},max_age=10,
expires=datetime.datetime.utcnow()+datetime.timedelta(days=3))
其中:
datetime.datetime.utcnow()表示当前时间
datetime.timedelta(days=3)表示3天
上面的代码表示设置cookie在当前时间的3天后失效
4.2 操作session(session默认在服务端保存15天)
获取session request.session[key]或者request.session.get(key)
设置session request.session[key]=value
删除session del request.session[key]
需要注意的是,删除服务端的session不会删除数据库中的session_data,而只是把session更新为一个其他的值
设置session的失效时间:
request.session.set_expiry(value)是设置session的失效时间
参数说明:
如果value是一个整数,session会在整数称后失效
如果value是个datatime或者timedelta,session会在这个时间之后失效
如果value是0,用户关闭浏览器后session就会失效
如果value是None,session会依赖全局session的失效策略
cookie和session的那些事的更多相关文章
- cookie 和 session 的一些事 中间件
cookie 和 session cookie 1. 保存在浏览器上一组组键值对,服务器让浏览器进行设置. 2. 为什么要用cookie? HTTP协议是无状态.使用cookie保存状态. 3. dj ...
- cookie、session和token那些事
cookie 和 session 众所周知,HTTP 是一个无状态协议,所以客户端每次发出请求时,下一次请求无法得知上一次请求所包含的状态数据,如何能把一个用户的状态数据关联起来呢? 比如在淘宝的某个 ...
- java的会话管理:Cookie和Session
java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...
- Django实现表单验证、CSRF、cookie和session、缓存、数据库多表操作(双下划綫)
通常验证用户输入是否合法的话,是前端js和后端共同验证的,这是因为前端js是可以被禁用的,假如被禁用了,那就没法用js实现验证合法与否了,也就是即使用户输入的不合法,但是也没提示,用户也不知道怎么输入 ...
- 关于Cookie和Session的优缺点
关于Cookie和Session的优缺点 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案. Cookie的优缺点:优点:极高的扩展性和可用 ...
- Cookie与Session详解
来源:<PHP核心技术与最佳实践> 列旭松 陈文 著 Cookie与Session详解读书笔记,从概念.操作.应用.注意事项以及区别等几方面详细阐述两者的基础知识,它们都是针对HTTP协议 ...
- 关于Cookie安全性设置的那些事
一.标题:关于Cookie安全性设置的那些事 副标:httponly属性和secure属性解析 二.引言 经常有看到XSS跨站脚本攻击窃取cookie案例,修复方案是有httponly.今天写出来倒腾 ...
- day07 Cookie 和 Session(非常重要)
day07 Cookie 和 Session 1. 会话技术 2. cookie 的方法和 cookie 案例-显示用户上次访问网站的时间 3. cookie 的细节 - 删除 cookie 4. S ...
- 【10】Cookie和Session
一.cookie和session的介绍 cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要"保持状态",因此cookie就是在这样一个场景下 ...
随机推荐
- CSS的box-sizing属性
box-sizing属性可以为三个值之一:content-box(default),border-box,padding-box. content-box,border和padding不计算入widt ...
- Gulp开发教程(翻译)
Building With Gulp =================== 原文地址 翻译出处 原创翻译,有不当的地方欢迎指出.转载请指明出处.谢谢! 对网站资源进行优化,并使用不同浏览器测试并不是 ...
- TCP/IP(三)数据链路层~1
前言 其实前面一堆讲的物理层的概念,会感觉特别的难理解,因为这是一个非常强大的计算机网络体系的底层知识,没有关系!我们大致了解一下就行了. 一.数据链路层概述 这是百度的简介 看图:理解一下,数据链路 ...
- hdu_1251统计难题(字典树Trie)
统计难题 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)Total Submi ...
- 在64位系统下,指向int型的指针占的内存空间多大?
不废话,请看代码演示如下: 注意使用的操作系统的位数,不同位数的操作系统,结果不一样! 我是用的是64位的操作系统! linux下示例代码如下: #include <stdio.h> in ...
- webpack的安装与使用
在安装 Webpack 前,你本地环境必须已安装nodejs. 可以使用npm安装,当然由于 npm 安装速度慢,也可以使用淘宝的镜像及其命令 cnpm,安装使用介绍参照:使用淘宝 NPM 镜像. 使 ...
- 如何开发由Create-React-App 引导的应用(三)
此文章是翻译How to develop apps bootstrapped with Create React App 官方文档 系列文章 如何开发由Create-React-App 引导的应用 如 ...
- [转载]织梦CMS首页调用分类信息栏目及列表方法
原文地址:织梦CMS首页调用分类信息栏目及列表方法作者:小武哥 不懂代码,搜索学习一晚上,都是说调用特定栏目分类信息列表的,用这个代码 {dede:arclistsg row='10' titlele ...
- dede从www跟目录迁移,网站空间
图集缩略图表名dede_uploads 字段url; 图集文章内部的图片表名dede_addonimages 字段imgurls 频道文章列表的图片 ...
- 关于IDE与环境变量的一点说明
环境变量就是当计算机要执行操作时,在环境变量所制定的范围内查找该操作. 比如linux的ls命令,计算机就需要在$PATH规定的目录中寻找该ls的可执行文件. java的classpath,在该规定的 ...