细说cookie和session的区别
做网站开发有一段时间了,而自己却发现对于cookie和session的基础理解存在不足,因此花了2天时间好好学习了一下cookie和session的特性,给大家分享一下
根本原因是HTTP协议是无状态的协议,就是当你通过客户端(电脑、手机)访问一个网站(服务器)的时候,服务器并不知道你是谁,假如你想看看自己的购买商品订单,服务器怎么给你返回数据呢?他必须要知道你是谁,cookie和session就是为了解决你是谁的问题。
cookie就是存放在客户端浏览器中的一段数据,每次访问某个网站的时候,浏览器会自动带着这段数据,提交给服务器,这样服务器就能识别客户端身份了。
name:cookie的名称
value:cookie的值
domain: cookie所属的域名,浏览器访问某个域名的时候,只会把该域名下的cookie发送给浏览器,a.shanhuxueyuan.com 和b.shanhuxueyuan.com是两个域名,cookie默认是不能共用的,只有设置改cookie的domain为“.shanhuxueyuan.com”才能共享cookie。
path: 可以访问此cookie的页面路径,如domain是shanhuxueyuan.com,path为/test/,那么只有shanhuxueyuan.com/test/路径下的页面可以读取此cookie。
expires/Max-Age: 此cookie的超时时间,当达到该时间后,cookie过期,如果不设置此值,当浏览器关闭后,cookie失效;删除cookie就是通过设置过期时间为当前时间之前的时间,来让cookie失效
size: cookie的大小
httpOnly: 如果设为true,只有http请求中会带有此cookie信息,不能通过js读取
secure:设置是否只通过https传递此值
客户端访问服务器--》服务器发送设置cookie的指令--》浏览器接收指令后存储cookie
例如客户端提交用户名和密码,服务器判断登录成功后,服务器设置cookie,在返回给浏览器的头文件Response Headers中会看到Set-Cookie,里面有要设置的cookie详细信息,浏览器接受后存储cookie。
下次再访问该服务器的时候,浏览器会把之前设置的cookie放在Request Headers中,发送给服务器
我们在baidu.com登录后,会发现,在百度图片、百度地图、百度文库等等都显示了登录,这就是因为他们进行了cookie的共享。
默认情况下,如果在某个域名下设置cookie,而不指定cookie的domain,该cookie只对当前域名有效。
在顶级域名shanhuxueyuan.com下设置cookie,如果不指定domain,则只有shanhuxueyuan.com下网址可以访问该cookie,如果想要共享给所有的子域名,则需要设置domain为“.shanhuxueyuan.com”,如果将domain设置为子域名,则该设置无效
setcookie("name1", "ceshi", time() + 3600);//shanhuxueyuan.com自己可以看到 setcookie("name3", "ceshi", time() + 3600, "/", ".shanhuxueyuan.com");//*.shanhuxueyuan.com都可以看到 setcookie("name4", "ceshi", time() + 3600, "/", "test.shanhuxueyuan.com");//设置无效
在二级域名 test.shanhuxueyuan.com下设置cookie,如果不指定domain,则只有test.shanhuxueyuan.com下网址可以访问该cookie,如果想要共享给该网站所有的域名,则需要设置domain为“.shanhuxueyuan.com”,如果将domain设置为其他子域名,则该设置无效
setcookie("name1", "ceshi", time() + 3600);//test.shanhuxueyuan.com自己可以看到 setcookie("name3", "ceshi", time() + 3600, "/", ".shanhuxueyuan.com");//*.shanhuxueyuan.com都可以看到 setcookie("name4", "ceshi", time() + 3600, "/", "test2.shanhuxueyuan.com");//设置无效
cookie是存储在客户端的,我们可以通过一些浏览器插件来很方便的查看和更改cookie
如果一个网站只通过cookie来存储用户信息,那么我们可以通过伪造cookie中的数据来实现一些越权操作,例如某个视频网站,将会员等级放在cookie里,通过普通账号登录之后,cookie中leval=1,只需将leval设为6,然后刷新页面,哈哈,直接变成vip身份了
session也是用来保持会话的,和cookie相比,session将信息存储在服务器端,由服务器来管理session。举个例子,我们去理发的时候有时候会让我办个会员卡,有一种会员卡是这样的,上面有10个空白框,你每次理发之后,都给你打个勾,下次再去这家店,服务员看一下你的卡上还有几个空白就知道你还能理几次发,这就相当于cookie,数据保存在客户端;另外一种会员卡是只有一张卡片,卡片上面会有卡号,你每次理发后,服务员在会员管理系统里面做一次记录,下次你来这家店,只需要报一下卡号就知道你还能理几次发。
session也是基于cookie 的,由于http是无状态的,假如我们只将用户数据存储在服务器端,当用户进行访问的时候,服务器还是不知道你是谁。所以session在存储的时候,会将sessionid返回给客户端,以cookie的形式保存。
以PHP为例,当我们第一次进行$_SESSION['count']操作时,可以看的,服务器会返回给浏览器Set-Cookie,sessionid存储在PHPSESSID中,不同语言存储的name可能不一样。
if(isset($_SESSION['count'])){ $_SESSION['count']=$_SESSION['count']+1; }else{ $_SESSION['count']=1; } echo "session count:".$_SESSION['count'];
session可以存储到内存、文件、数据库中,可以根据你使用的语言的配置文件来进行配置,比如PHP.ini,我用的是PHP的YII框架,可以很方便的在配置文件中配置session路径
'components' => [ 'session' => [ 'savePath'=>dirname(dirname(__DIR__)).'/session', ], ]
session在文件中存储形式如下,文件名为“sess_”加上session_id
也可以配置到数据库中,请自行根据所使用语言进行配置,本文只提供思路,与开发语言无关
'session' => [ 'class' => 'yii\web\DbSession',//使用数据库存储session 'db' => 'db', //存储session的数据库配置 'sessionTable' => 'session',//存储session的表名 ],
数据库的结构如下:id、过期时间和data
CREATE TABLE session ( id CHAR(32) PRIMARY KEY, expire INTEGER, data TEXT )
在数据库中存储的形式如下
假如我们有两个域名www.shanhuxueyuan.com 和 test.shanhuxueyuan.com,想要实现在顶级域名下登录后,同样在子域名下也显示登录,登录采取session保存用户数据,如果实现session的共享呢?上面我们看到了,服务器端有很多session文件,当服务器处理一次客户端请求时,会根据客户端发送的cookie中的PHPSESSID,来找到相应的session记录,所以要实现session共享,我们必须满足以下两个条件:
1.顶级域名和子域名的session要存储在一个文件内,在前面我们有讲到,可以根据配置文件来配置session的存储位置,如存储到一个文件夹下或者是同一个数据库表中
2.cookie中的PHPSESSID作用域domain应该包含多个域名,我是设置为“*.shanhuxueyuan.com”
在进行session操作时,一般都会默认设置一个PHPSESSID的cookie,只是默认的cookie只对当前域名有效,因此需要单独设置此cookie,PHPSESSID的值取session id
if(isset(\Yii::$app->session['count'])){ \Yii::$app->session['count']+=1; }else{ \Yii::$app->session['count']=1; setcookie('PHPSESSID',\Yii::$app->session->id,0,'','.zhefuyijiu.com'); //手动设置PHPSESSID的domain }
我们前面看到了,session是存储在服务器上的,如果不回收就会越来越多,我们可以设置session的有效期,如1个小时,每次进行一些session的读写操作,session的过期时间都会设置为当前时间+1小时,除非你1个小时不进行任何操作。
在PHP内部机制中,当php被请求了N次后就会有一次触发回收机制。到底是请求多少次触发一次是通过以下两个参数控制的。而cookie则是指定了一个固定的过期时间,只要到时cookie就会失效,session则是多久不操作才会失效。
session.gc_probability = 1 session.gc_divisor = 100
我们常说关闭浏览器,session就失效了,其实是不正确的,关闭客户端浏览器,并不会导致服务器session的删除,只是关闭浏览器后,存储PHPSESSID的cookie失效了,下次再次访问,是一个新的PHPSESSID了,给我们的感觉是session失效了,假如设置PHPSESSID的cookie失效时间很长,则session在关闭浏览器后仍然有效。
cookie存储在客户端;
session存储在服务器;
session的使用依赖session id,而session id存储在cookie中
cookie和session都可以用来跟踪会话
cookie很容易被伪造,因此建议存储一些不太重要的数据,如一些表单数据;而使用session来存储重要隐私数据
cookie可以通过设置domain来实现多个域名共享;session需要通过维护session的存储位置和session id来实现共享
cookie可以指定一个固定的过期时间,而session是在多久不进行操作才失效
以上内容为本人原创,转载请注明来源,由于本人水平有限,如有错误还请不吝指正,感谢~
点赞(0)