刚使用Codeigniter时也被其中的SESSION迷惑过,后来就再也没用过CI自带的SESSION,想必仍是有必要整理一下SESSION。为弄清CI中的SESSION,先来讲一下PHP中SESSION是如何工做的。因为HTTP协议自己是无状态的,因此当保留某个用户的访问状态信息时,须要客户端有一个惟一标识传给服务端,这个惟一标识就是SESSION ID,存放在客户端的COOKIE中,而后服务端根据该标识读取存放的用户状态信息,达到保存会话状态的目的。PHP中启动一个会话须要执行下面语句:php
1
|
session_start();
|
一、客户端每次请求时会有一些信息存放中HTTP头中发送给服务端,以用户第一次访问为例:html
Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:s.local
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36web
二、服务端接到请求处理后并返回给客户端,并在HTTP Response中加上添加COOKIE的请求,告诉浏览器须要设置一个COOKIE,COOKIE名为PHPSESSID,值为r887k5n4scg32d4ba34huuhmq7,如:chrome
Response Headers
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Length:0
Content-Type:text/html
Date:Sun, 08 Dec 2013 12:56:56 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=5, max=100
Pragma:no-cache
Server:Apache/2.2.11 (Win32) PHP/5.4.7
Set-Cookie:PHPSESSID=r887k5n4scg32d4ba34huuhmq7; path=/
X-Powered-By:PHP/5.4.7数据库
三、当客户端再次访问该网站的页面时,浏览器会将该COOKIE发送给服务端,服务端根据COOKIE的值去读取服务器上存放SESSION的文件,拿到到会话信息,如:浏览器
Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:PHPSESSID=r887k5n4scg32d4ba34huuhmq7
Host:s.local
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63服务器
从而达到保存会话状态的目的。但也须要注意,若是获取到用户A登陆的SESSION ID会怎么样?根据上面的逻辑,若是在请求过程当中把获取到的SESSION ID一并发送给服务端,服务端根据SESSION ID读取文件,发现文件内容存在,从而断定用户为A用户,也就是获取到了A用户的用户状态,从而可能能够进行一些敏感操做。因此在会话有效期内,获取到了SESSION ID即获取到了用户的受权,这是比较危险的,以本地的一个管理系统为例,经过chrome登陆后查看到客户端COOKIE以下图:cookie
假如若是经过某种手段获取到了SESSION ID, 能够模拟发送一个相同的COOKIE过去便可实现登陆。FireFox中可添加COOKIE,打开Firebug后Cookies中新建cookie,肯定以后刷新页面便可登陆到管理系统,以下图:session
一般状况下可经过js获取到cookie,因此须要注意转义,防止数据展现时被执行了。接下来看看CI中的SESSION。在配置文件中有几个跟Session配置相关的参数,影响到Session的使用,它们是:并发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//session保存在cookie中的名称
$config
[
'sess_cookie_name'
] =
'ci_session'
;
//session的有效时间
$config
[
'sess_expiration'
] = 7200;
//是否关闭浏览器session失效
$config
[
'sess_expire_on_close'
] = FALSE;
//SESSION是否加密存放在COOKIE中
$config
[
'sess_encrypt_cookie'
] = FALSE;
//是否保存在数据库中
$config
[
'sess_use_database'
] = FALSE;
//存在数据库中,则数据库表名
$config
[
'sess_table_name'
] =
'ci_sessions'
;
//是否匹配IP
$config
[
'sess_match_ip'
] = FALSE;
//是否匹配UserAgent
$config
[
'sess_match_useragent'
] = TRUE;
//更新时间时间
$config
[
'sess_time_to_update'
] = 300;
|
CI自带的SESSION没有服务端文件存储,全部的信息都存放在客户端COOKIE中,当调用$this->load->library('session');时会启动一个会话,即设置一个COOKIE,COOKIE的内容以下:
Array
(
[session_id] => f05138a9513e4928cb0a57672cfe3b53
[ip_address] => 127.0.0.1
[user_agent] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
[last_activity] => 1386569398
[user_data] =>
)
当客户端请求时会将这些信息在HTTP头中传输给服务端,服务端从HTTP头中读取到SESSION信息。一样的能够实现会话,但该方式有不少的不肯定因素,根据源码说几点吧:
一、 若是日志文件中出现:The session cookie data did not match what was expected. This could be a possible hacking attempt.说明两个问题:a.sess_encrypt_cookie为false,SESSION在COOKIE中未加密存放 b.读取到COOKIE后,校验失败。涉及到加解密、参数处理的状况,容易出现匹配不经过的状况,若不经过则清空SESSION。
二、若是sess_match_ip为true,当客户端IP变化时,SESSION将校验不经过,从而清空SESSION。
三、sess_match_useragent默认为true,当客户端UserAgent变化时,校验不经过,清空SESION。简单的例子,经过IE浏览器访问,若切换到不一样的IE模式,Agent不一样,因此校验不经过,清空SESSION。
能够看到,当出现上面任何一种状况时,SESSION都会清空,出现登陆不成功或者跳转到登陆页面的状况。若是说不加密、不校验IP、UserAgent呢?由于COOKIE是存放在客户端,须要伴随HTTP请求发给服务端,一来过多的COOKIE会影响速度,对一些图片等资源来讲彻底时浪费带宽;二来COOKIE只能存储4K的数据,加密处理后能存放的更小。
种种的不肯定因素将产生各类奇怪的问题,避免过多的纠结,果断改用其余方式吧。
--EOF--除非注明,博客文章均为原创,转载请以连接形式标明本文地址本文地址: http://pengbotao.cn/codeigniter-session.html