一、 session与cookie认识
(1)session与cookie是什么
它们都是文件,只不过保存的位置不同。
Session文件默认保存在服务器的临时文件夹内,形式如下:
Cookie文件分为内存cookie和硬盘cookie
内存cookie一般是会话cookie,这类cookie没有指定它生命周期,保存在浏览器运行时的内存空间中,当浏览器关闭后,cookie文件消失。
硬盘cookie一般是自己设定的cookie, 并设置了它的生命周期,在生命周期类会保存在浏览器默认的文件夹下,不同浏览器cookie的保存位置不同。Cookie形式如下:
(2)session与cookie的作用
是用来在不同页面间传递信息的。比如用户登录信息在不同页面间传输,我们称之为会话。由于HTTP是无状态的,不能区分前一次访问和后一次访问的是谁,如果不进行处理,那我们登录网站后,访问网站的其他页面就又要登录一次,很麻烦,所以用一个文件把上次登录的信息保存起来,在访问其他页面时,读取那个文件的信息,就可以确认用户的访问状态,不用再重复登录操作了。把实现这种功能的过程称为会话,也有的称为会话追踪。Session和cookie就是保存这些会话信息的文件。
实现会话的方式:
1. 纯cookie方式:只用cookie保存会话信息。
优点:服务器无压力,减少了服务器很多工作
缺点:1.不安全,可以在客户端看到会话信息
2.受限制,cookie文件能否生成,其大小,个数受到浏览器的限制
2. 纯session方式:只用session保存会话信息
优点:安全,会话信息全在服务器中,外界难以获取
确定:服务器压力大,但只要服务器性能好,这种方式是最好的,安全第一。
3. Session和cookie联合使用:是常用的方式
4. 使用URL传递会话信息:是N年前使用的方式。
优点:传递小量信息时方便快捷
缺点:1.不安全:在URL地址栏直接能看到会话信息
2.受限制:URL地址栏能传递的信息是有限的
3.编码量大:在每一个页面都要加一个将会话信息发送到URL的代码
5.自定义处理机制:如果你够牛,可以设计一个比session,cookie更好的处理会话的机制。
二、 PHP的session与cookie机制
(1) 机制介绍:何为机制,当然就是系统自动处理了,不用人为进行的操作,php会对session和cookie进行一些自动的操作
(2) 机制详解:
-
浏览器请求服务器时,会先检测本地是否有cookie,有则cookie就会出现在在请求头中发送给服务器,请求头域信息如下:
-
服务器接收浏览器请求时:
a. 如果请求中有cookie,则会将这个cookie保存到$_COOKIE中:
键名为cookie名,键值为cookie值。开启会话时(session_start),根据这个cookie名区分是不是本网站的cookie,如果是则根据cookie值在服务器session文价夹中查找这个session文件,没找到则创建以这个值为名的session文件。
b. 如果请求中没有cookie,则在开启会话时,生成一个session.id,在$_COOKIE数组中保存一个键名为session.name,键值为session.id的元素,并将这个元素以set-cookie响应头传给浏览器,在浏览器端生成一个内存cookie,形式如下:
注:Session.name:是服务器默认的cookie的名字,通过这个名字判断浏览器发送的cookie是不是本网站的cookie。php.ini中可设置
Session.id:是一个唯一的字符串(服务器根据IP地址生成,只有服务器能识别),是浏览器端内存cookie的值,是服务器中session文件的名字,不同用户的会话信息存放在不同的session文件中。
c. 当脚本结束时,若没有执行session_destroy();则会自动将SESSION数组中的数据序列化后保存到session文件中。使用cookie登录时会自动将session中的数据反序列化存入$_SESSION数组。
-
垃圾回收机制
用户访问网站时就会生成一个session文件,用户在访问结束后,如果不点击退出登录,直接关闭浏览器或窗口,session文件是不会删除的,长此以往,服务器中就会有n个session文件,占用空间且影响查找速度。所以要对这些文件进行处理,故设置了一个垃圾回收机制。-
机制执行方式:服务器运行期间会有概率的执行垃圾回收机制,机制执行时会扫描目录所有session文件,根据他们最后修改的时间判断是否过期,所有过期的session文件都会被删除。session.gc_maxlifetime=1440 单位是秒,可以设置session文件的生命周期session文件最后的修改时间+1440秒 超过了系统当前时间,则过期了,但过期了不一定被删除,只有在机制执行时才会被删除。
-
机制触发条件:
session.gc_probability = 1 被除数
session.gc_divisor = 1000 除数
机制有 被除数/除数 的概率被触发,为什么要按概率触发,原因如下:a. 性能方面:系统判断ssession文件是否过期默认是通过文件的最后修改时间来确定的,如果要精确的删除每个过期的session就要不断地对session目录的每个session文件访问,session文件何其多,真这样做系统就干不了别的什么了。
b. 正确性:在服务器上可设置默认的gc参数,在每个运行的脚本中也可以自定义gc参数,不同脚本的session过期时间可以不同,如果脚本的session文件在同一个目录下,则系统会以值最小的时间进行删除操作,导致还在生命周期的session文件也被删除,有概率的触发可以减少误删。综上所述,按概率删除是最合理的。(对于系统默认的机制而言)
-
三、 传递session_id的方式
会话的核心就是session_id的传递,因为会话信息就保存在以其为名的session文件中。
-
通过cookie传递:前提是浏览器支持cookie
-
URL重写:session.use_trans_sid = 1,在浏览器不只持cookie时,自动跨页传送,就是将session_id加在url地址栏,以get方式传送,不安全。
-
隐藏表单传递:使用表单的隐藏域,这样每个页面都要加一个隐藏域,代码量大,且不算安全,因为就算是post方式,也是可以抓包的,完全可以看到里面信息。
-
使用文件或数据库存储:将session文件,session_id保存到文件或数据库中,在需要时从中取出,这是最安全的。
四、 Session与cookie的操作
我们也可以手动的对Session与cookie操作。
-
设置cookie:设置cookie内数据的有效时间及使用特性。
(1)创建cookie:
setcookie(“名”,“值”,“有效时间”,“作用路径”,“作用域名”,“是否只在https下使用”,“是否只在http协议下传输”);
如:setcookie(session_name(),session_id(),time()+36000000);
就可以使用cookie直接登录网站了,不用再输入用户名。(2)删除cookie:
setcookie(“名”,”值”,time()-1); -
设置session:
不能直接操作session文件,但可以通过SESSION数组向session文件读取和写入数据。($_SESSION是开启会话后才有的)
(1)创建session文件:session_start();系统就会自动生产一个session文件。
(2)删除session文件:session_destory;删除当前脚本创建的session文件。
五、 会话与安全
(1) 一个完整的会话
-
开启会话:
session_start(); 前面不能由任何输出,因为它会发一个响应头,这个过程生成session文件,并在浏览器生成内存cookie,并使$_COOKIE[session_name()] = session_id()
;,$_SESSION = array();
注意:$_SESSION
数组是在开启会话后创建的。 -
注册会话:
就是在$_SESSION
数组中保存会话信息。如
$_SESSION[‘user’] = “小明”
;$_SESSION[‘paw’] = “123”;
…… -
使用会话:
就是使用$_SESSION
数组中的信息。
如:$user = $_SESSION[‘user’];
-
删除会话:
分2个步骤:
(1)清除会话变量:
$_SESSION[‘goods’] = null;
删除单个会话变量,如清除购物车中的某个商品。
$_SESSION = array()
;
session_unset();
这2个操作都是一样的效果:注销当前用户所有的会话信息,保留$_SESSION
数组,指向session文件的文件句柄会在脚本结束后关闭。用户再次访问网站某个页面时需要重新输入登录信息。若其后没有session_destroy()操作,在脚本结束时,会将session文件内容清空(session文件还保存着,是个空文件)。
unset($_SESSION);
注销当前用户所有的会话信息,并销毁$_SESSION
数组,但指向session文件的文件句柄仍然存在,脚本结束后也继续存在。用户再次访问网站某个页面时需要重新输入登录信息。在脚本结束时,不会对session文件处理。
(2) 清除session文件:
session_destroy();
删除session文件,并关闭文件句柄。对会话变量无操作,即$_SESSION
数组中数据仍可以使用。
(2) 安全:防止用户账号和数据被他人获取。
1.若电脑安装了流氓软件,它可以获取浏览器的cookie用其登录你的账号。可以在每次退出网站时点击退出,这种方式就失效了。
2.可以伪造session_id,不断尝试登录,总会有一次登录成功。可以对登录次数进行限制,设置验证码。
六、 如何精确设定session文件的存在时间
-
将cookie过期时间和session过期时间设置相同。
-
为每一个session值增加一个timestamp。
-
每次访问之前判断时间戳。
七、 相关函数和配置项
php.ini配置项
Session.save_handler = file /user 使用文件方式存储session(默认)
Session.auto_start = 0 是否自动开启session
Session.save_pate = d:/tmp session存储目录
Session.use_strict_mode = 0 是否接受非服务器创建的session
Session.use_cookies = 1 是否使用cookie传递session_id
Session.cookie_secure = 0 是否只在https协议下使用
Session.use_only_cookies = 1 是否只用一种方式(cookie)传递session_id
Session.cookie_httponly = 0 是否只在http协议下传输
Session.cookie_domain = localhost cookie作用路径
Session.cookie_path = www/myweb cookie作用域名
Session.serialize_handler = php 使用php进行序列化
Session.name = PHPSESSION 会话名(会话cookie名)
Session.gc_probability = 1
Session.gc_divisor = 100
Session.gc_maxlifetime = 1440 session文件过期时间
函数:
Session_start();
Setcookie();
Session_name();
Session_id();
Session_unset();
Session_destroy();
八、 Session缓存
九、 当访问量大时session如何处理。