细说cookie和session的区别

蛰伏已久 蛰伏已久 2018-01-10

做网站开发有一段时间了,而自己却发现对于cookie和session的基础理解存在不足,因此花了2天时间好好学习了一下cookie和session的特性,给大家分享一下


1. 为什么需要cookie和session

      根本原因是HTTP协议是无状态的协议,就是当你通过客户端(电脑、手机)访问一个网站(服务器)的时候,服务器并不知道你是谁,假如你想看看自己的购买商品订单,服务器怎么给你返回数据呢?他必须要知道你是谁,cookie和session就是为了解决你是谁的问题。


2.关于cookie

2.1 什么是cookie

  cookie就是存放在客户端浏览器中的一段数据,每次访问某个网站的时候,浏览器会自动带着这段数据,提交给服务器,这样服务器就能识别客户端身份了。


2.2 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传递此值


2.3 cookie的设置过程

    

     客户端访问服务器--》服务器发送设置cookie的指令--》浏览器接收指令后存储cookie


     例如客户端提交用户名和密码,服务器判断登录成功后,服务器设置cookie,在返回给浏览器的头文件Response Headers中会看到Set-Cookie,里面有要设置的cookie详细信息,浏览器接受后存储cookie。

    201709061504684065707192.png

   下次再访问该服务器的时候,浏览器会把之前设置的cookie放在Request Headers中,发送给服务器

   


 201709061504684714627685.png

    

  2.4 cookie的作用域

   我们在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");//设置无效

   

 2.5 伪造cookie

     cookie是存储在客户端的,我们可以通过一些浏览器插件来很方便的查看和更改cookie

    201709061504690082426811.png

   如果一个网站只通过cookie来存储用户信息,那么我们可以通过伪造cookie中的数据来实现一些越权操作,例如某个视频网站,将会员等级放在cookie里,通过普通账号登录之后,cookie中leval=1,只需将leval设为6,然后刷新页面,哈哈,直接变成vip身份了


3.关于session

3.1 什么是session

    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'];


201709071504747844818880.png


3.2 session的存储

    session可以存储到内存、文件、数据库中,可以根据你使用的语言的配置文件来进行配置,比如PHP.ini,我用的是PHP的YII框架,可以很方便的在配置文件中配置session路径

'components' => [
        
        'session' => [
            'savePath'=>dirname(dirname(__DIR__)).'/session',
        ],
]

    session在文件中存储形式如下,文件名为“sess_”加上session_id

  201709071504766930189343.png




也可以配置到数据库中,请自行根据所使用语言进行配置,本文只提供思路,与开发语言无关

 '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 
    )

在数据库中存储的形式如下

201709071504767102956738.png


3.3 session的共享

 假如我们有两个域名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
            }

 

3.4 session的回收

   我们前面看到了,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在关闭浏览器后仍然有效。

4.cookie和session的对比

  cookie存储在客户端;

   session存储在服务器;

   session的使用依赖session id,而session id存储在cookie中

   cookie和session都可以用来跟踪会话

   cookie很容易被伪造,因此建议存储一些不太重要的数据,如一些表单数据;而使用session来存储重要隐私数据

   cookie可以通过设置domain来实现多个域名共享;session需要通过维护session的存储位置和session id来实现共享

   cookie可以指定一个固定的过期时间,而session是在多久不进行操作才失效

  

以上内容为本人原创,转载请注明来源,由于本人水平有限,如有错误还请不吝指正,感谢~

分享到

点赞(0)