----- 最近更新时间【2021-12-14】-----
一、会话
在讲理Cookie与Session之前,写这里先引入一个叫做会话的概念。
在计算机术语中,会话是指一个终端用户与交互系统进行通讯的过程,比如从输入账户密码进入操作系统到退出操作系统就是一个会话过程。会话较多用于网络上,TCP的三次握手就创建了一个会话,TCP关闭连接就是关闭会话。
会话跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。而使用会话跟踪技术,则可以弥补HTTP协议无状态的不足。
二、COOKIE
1、简介
Cookie技术是客户端的解决方案,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。
让我们说得更具体一些:当用户使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头(Response Header)。当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置,客户端再向服务器发送请求的时候,都会把相应的Cookie再次发回至服务器。而这次,Cookie信息则存放在HTTP请求头(Request Header)了。有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。
2、Cookie的查看
不同的浏览器采用不同的方式保存Cookie,对于IE浏览器而言,以前我们可以从: [系统盘]:\Users\[用户名]\AppData\Local\Microsoft\Windows\INetCookies
目录中找到存储的Cookie,但是现在我们只能从里面的文件里看到这样的一句话:
Cookies are no longer stored in files. Please use Internet*Cookie* APIs to access cookies.
这句话大概意思就是“cookie不再储存在文件夹了,你需要通过http相关的api才能查看cookies信息”。在早期Cookies技术,Cookies一般都是作为一个临时文件存储在客户端本地,为了安全性考虑,现在存本地的越来越少,很多都是通过API存这些数据。
这里我重新介绍两种查看Cookies的方法,第一种是Fiddler工具或者浏览器F12,第二种在Chrome浏览器直接点击。
1)Fiddler
使用Fiddler查看cookies,在响应头中看 set-cookies字段即可。
浏览器则是:F12 > Application > Cookies
2)Chrome
在Chrome浏览器地址栏左侧点击进去就可以查看。
或者在Chrome浏览器设置里面查看。
3、Cookie的原理
当服务器返回给客户端一个http响应信息时,其中如果包含Set-Cookie这个头部时,意思就是指示客户端建立一个cookie,并且在后续的http请求中自动发送这个cookie到服务器端,直到这个cookie过期。如果cookie的生存时间是整个会话期间的话,那么浏览器会将cookie保存在内存中,浏览器关闭时就会自动清除这个cookie。另外一种情况就是保存在客户端的硬盘中,浏览器关闭的话,该cookie也不会被清除,下次打开浏览器访问对应网站时,这个cookie就会自动再次发送到服务器端。一个cookie的设置以及发送过程分为以下四步:
- 客户端发送一个http请求到服务器端
- 服务器端发送一个http响应到客户端,其中包含Set-Cookie头部
- 客户端发送一个http请求到服务器端,其中包含Cookie头部
- 服务器端发送一个http响应到客户端
4、Cookie的基本操作
1)创建cookie
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
setcookie() 定义了 Cookie,会和剩下的 HTTP 头一起发送给客户端。 和其他 HTTP 头一样,必须在脚本产生任意输出之前发送 Cookie(由于协议的限制)。 请在产生任何输出之前(包括 <html> 和 <head> 或者空格)调用本函数。
一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE 读取。
如果在调用本函数以前就产生了输出,setcookie() 会调用失败并返回 FALSE。 如果 setcookie() 成功运行,返回 TRUE。当然,它的意思并非用户是否已接受 Cookie。
2)获取cookie
$_COOKIE['name']
问题:客户端的cookie信息是怎么传递给服务器的?
通过http协议的Cookie:name=test;这个机制是http协议规定的。
3)更新cookie
更新某个cookie的key<==>val,实际是就是重新设置;依然是使用setcookie();
4)删除cookie
指定删除某个cookie,只需要把这个key的time设置成time()-秒数
即可。
如:setcookie('name','',time()-1);
如果需要删除所有的cookie则可以用遍历的方法:
foreach($_COOKIE as $key=>$val){
setcookie($key,'',time()-1);
}
如果你把这个网站的所有cookie都删除掉,则浏览器会自动把这个cookie文件也删除掉的。
5、注意
1)Cookie功能需要浏览器的支持。
如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。
2)Cookie具有不可跨域名性。
Cookie在客户端是由浏览器来管理的,Cookie是不可跨域名的。如域名www.google.com颁发的Cookie不会被提交到域名www.baidu.com去。这是由Cookie的隐私安全机制决定的。
三、SESSION
1、简介
Session 是存放在服务器端的,类似于Session结构来存放用户数据,当浏览器 第一次发送请求时,服务器自动生成了一个Session和一个Session ID用来唯一标识这个Session,并将其通过响应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的Session。
2、Seesion的工作原理
简单的说,当你登录一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上面。客户端每次请求服务器的时候会发送 当前会话的session_id,服务器根据当前session_id判断相应的用户数据标志,以确定用户是否登录,或具有某种权限。
由于数据是存储在服务器 上面,所以你不能伪造,但是如果你能够获取某个登录用户的session_id,用特殊的浏览器伪造该用户的请求也是能够成功的。
session_id是服务器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性。
Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效
3、Seesion的基本用法
1)保存sesion
session_start(); //初始化session
$_SESSION['name'] = 'nosee123';
查看服务器的session文件,存储结果如:name|s:8:"nosee123";
上面的s
表示保存类型为字符串,8
为表示所保存数据的字节大小,最后nosee123
是session的值。
seesion文件中可以存储的类型有如:string、float、integer、bool、array、object。
2)获取sesion数据
session_start(); //初始化session
$name = $_SESSION['name'];
注意:如果我们需要取出对象,则需要实现申明一下类的定义信息。(如:可以使用require_once来解决)
3)删除seesion数据
删除某个key:
unset($_SESSION['key']);
删除所有session:
session_destroy(); //相当于删除整个对应的session文件
4、配置说明
在配置文件php.ini中我们可以作一些session的配置。
1)session.auto_start
指定会话模块是否在请求开始时自动启动一个会话。默认为 0(不启动,也不推荐启用)。
此时使用$_SESSION前要先调用session_start()初始化session。
2)session.name
session.name = PHPSESSID
默认值为PHPSESSID;用于设置session的名字,该值可以通过session_name()
获取。
3)session.save_path
session的保存路径,默认为:session.save_path = "/var/lib/php/sessions"
。
4)垃圾回收
-- session.gc_maxlifetime = 1440
这个时间是指在1440秒(24分钟)内,没有使用session文件,该session就会被当做垃圾回收。
-- session.gc_probability = 1
与session.gc_divisor = 1000
,ession.gc_divisor 与 session.gc_probability 合起来定义了在每个会话初始化时启动 gc(garbage collection 垃圾回收)进程的概率。此概率用 gc_probability/gc_divisor
计算得来。例如 1/1000 意味着在每个请求中有 0.1% 的概率启动 gc 进程。如果网站的规模越大,我们建议把这个概率设置越小。
5)session.use_cookie
session.use_cookies = 1
设置是否使用cookie,默认使用。
6)session.cookie_lifetime
session.cookie_lifetime = 0
cookie保存时间,默认0,关闭浏览器就失效
7)session.use_trans_sid
session.use_trans_sid 指定是否启用透明 SID 支持。默认为 0(禁用)。
8)session.save_handler
session.save_handler 定义了来存储和获取与会话关联的数据的处理器的名字。默认为 files。
session数据还可以存放的位置如:数据库(mysql),内存(redis、memcache),网络文件(nfs)
5、禁用cookie的情况
当用户禁用cookie后,服务器每次session_start()都会创建一个全新的session文件。
解决办法:
方法一,在每个超链接上添加一个PHPSESSIONID=$sessionId
//在每个超链接上添加一个PHPSESSIONID=$sessionId;同时每个页面加入:
if(isset($_GET['PHPSESSIONID'])){
session_id($_GET['PHPSESSIONID']); //设置session_id();
}
session_start(); //若有设置session_id()则sesssion_start()不会创建一个新的session文件。
//$sessionId = session_id();
方法二,使用常量SID
SID是一个包含着会话名以及会话 ID 的常量,格式为 "name=ID",它的值相当于字符串"session_name().'='.session_id()
";或者如果会话 ID 已经在适当的会话 cookie 中设定时则为空字符串。
可以在超链接(herf)、action、header(Location:xxx)里直接拼接SID
常量,如
<a href="index.php?<?php echo SID; ?>">下个页面</a>
方法三,使用session.use_trans_sid指定是否启用透明SID支持
直接配置php.ini文件的session.use_trans_sid = 0
,把0改为1即可。(配置成功后则在herf、action、header中会自动加SID,但是javascript的跳转中不会自动添加)
但是该方法对安全有影响,不推荐开启。
6、注意
1)在使用$_SESSION前要保证session被初始化,具体方法如下:
方法一:先调用session_start();
方法二:配置php.ini的session.auto_start=1(不推荐,会影响效率)
2)一个会话对应一个session:
当关闭浏览器再打开操作session后,会创建一个新的session文件。
3)误解:“只要关闭浏览器,session就消失了”
产生这种错觉的原因:当关闭浏览器后这个 session_id就消失了,再次连接服务器时也就无法找到原来的session。
恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,所以session的gc机制都会有存在的意义。
四、COOKIE与SESSION
1)存放位置
cookie数据存放在客户的浏览器上,session数据放在服务器上。
2)安全性
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
3)网络传输量
cookie通过网络在客户端与服务器传输,而session保存在服务器不需要传输。
cookie每次请求都会被自动添加到Request Header中,无形中增加了流量。cookie信息越大,对服务器请求的时间越长。
4)生命周期(以20分钟为例)
cookie的生命周期是累计的,从创建开始计时,20分钟后cookie生命周期结束,cookie失效。
session生命周期是间隔的,从创建计时,如在20分钟内没有访问过session,那么session信息无效;如果在第19分钟访问过session,那么它的生命周期将重新开始计算。
5)服务器性能:
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。考虑到减轻服务器性能方面,应当使用COOKIE。
6)储存大小:
单个cookie在客户端的限制一般是4K,就是说一个站点在客户端存放的COOKIE不能超过4K,有些浏览器会限制一个站点最多保存20个cookie。Session对象没有对存储的数据量的限制,也可以保存更为复杂的数据类型。
7)保存内容
cookie保存的是字符串,session中可以保存多种数据类型。
参考
官方手册:
cookie: http://php.net/manual/zh/features.cookies.php
seesion: http://php.net/manual/zh/book.session.php
《THE END》