CodeIgniter配置之SESSION用法实例分析


Posted in PHP onJanuary 19, 2016

本文实例讲述了CodeIgniter配置之SESSION用法。分享给大家供大家参考,具体如下:

刚使用Codeigniter时也被其中的SESSION迷惑过,后来就再也没用过CI自带的SESSION,想必还是有必要整理一下SESSION。为弄清CI中的SESSION,先来说一下PHP中SESSION是如何工作的。由于HTTP协议本身是无状态的,所以当保留某个用户的访问状态信息时,需要客户端有一个唯一标识传给服务端,这个唯一标识就是SESSION ID,存放在客户端的COOKIE中,然后服务端根据该标识读取存放的用户状态信息,达到保存会话状态的目的。PHP中启动一个会话需要执行下面语句:

session_start();

1、客户端每次请求时会有一些信息存放中HTTP头中发送给服务端,以用户第一次访问为例:

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.36

2、服务端接到请求处理后并返回给客户端,并在HTTP Response中加上添加COOKIE的请求,告诉浏览器需要设置一个COOKIE,COOKIE名为PHPSESSID,值为r887k5n4scg32d4ba34huuhmq7,如:

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

3、当客户端再次访问该网站的页面时,浏览器会将该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如下图:

CodeIgniter配置之SESSION用法实例分析

假如如果通过某种手段获取到了SESSION ID, 可以模拟发送一个相同的COOKIE过去即可实现登录。FireFox中可添加COOKIE,打开Firebug后Cookies中新建cookie,确定之后刷新页面即可登录到管理系统,如下图:

CodeIgniter配置之SESSION用法实例分析

通常情况下可通过js获取到cookie,所以需要注意转义,防止数据展示时被执行了。接下来看看CI中的SESSION。在配置文件中有几个跟Session配置相关的参数,影响到Session的使用,它们是:

//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信息。同样的可以实现会话,但该方式有很多的不确定因素,根据源码说几点吧:

1、如果日志文件中出现: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。

2、如果sess_match_ip为true,当客户端IP变化时,SESSION将校验不通过,从而清空SESSION。

3、sess_match_useragent默认为true,当客户端UserAgent变化时,校验不通过,清空SESION。简单的例子,通过IE浏览器访问,若切换到不同的IE模式,Agent不同,所以校验不通过,清空SESSION。

可以看到,当出现上面任何一种情况时,SESSION都会清空,出现登录不成功或者跳转到登录页面的情况。如果说不加密、不校验IP、UserAgent呢?因为COOKIE是存放在客户端,需要伴随HTTP请求发给服务端,一来过多的COOKIE会影响速度,对一些图片等资源来说完全时浪费带宽;二来COOKIE只能存储4K的数据,加密处理后能存放的更小。

种种的不确定因素将产生各种奇怪的问题,避免过多的纠结,果断改用其他方式吧。

希望本文所述对大家基于CodeIgniter框架的PHP程序设计有所帮助。

PHP 相关文章推荐
PHP+JS+rsa数据加密传输实现代码
Mar 23 PHP
php mysql 判断update之后是否更新了的方法
Jan 10 PHP
深入PHP操作MongoDB的技术总结
Jun 02 PHP
linux使用crontab实现PHP执行计划定时任务
May 10 PHP
php判断文件上传类型及过滤不安全数据的方法
Dec 17 PHP
php+mysqli使用面向对象方式查询数据库实例
Jan 29 PHP
php实现cookie加密的方法
Mar 10 PHP
php封装的连接Mysql类及用法分析
Dec 10 PHP
程序员的表白神器“520”大声喊出来
May 20 PHP
PDO::query讲解
Jan 29 PHP
PHP PDOStatement::debugDumpParams讲解
Jan 30 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
Feb 12 PHP
CodeIgniter配置之routes.php用法实例分析
Jan 19 #PHP
CodeIgniter配置之config.php用法实例分析
Jan 19 #PHP
Codeigniter控制器controller继承问题实例分析
Jan 19 #PHP
php pthreads多线程的安装与使用
Jan 19 #PHP
PHP+swoole实现简单多人在线聊天群发
Jan 19 #PHP
PHP各种异常和错误的拦截方法及发生致命错误时进行报警
Jan 19 #PHP
[原创]CI(CodeIgniter)简单统计访问人数实现方法
Jan 19 #PHP
You might like
使用ThinkPHP自带的Http类下载远程图片到本地的实现代码
2011/08/02 PHP
PHP提示Notice: Undefined variable的解决办法
2012/11/24 PHP
php常见的魔术方法详解
2014/12/25 PHP
PHP中异常处理的一些方法整理
2015/07/03 PHP
php+jQuery ajax实现的实时刷新显示数据功能示例
2019/09/12 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
Javascript实例教程(19) 使用HoTMetal(4)
2006/12/23 Javascript
JavaScript 原型继承之构造函数继承
2011/08/26 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
2013/01/23 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
2015/01/28 Javascript
JS弹出可拖拽可关闭的div层完整实例
2015/02/13 Javascript
10条建议帮助你创建更好的jQuery插件
2015/05/18 Javascript
理解js回收机制通俗易懂版
2016/02/29 Javascript
jquery html动态添加的元素绑定事件详解
2016/05/24 Javascript
Javascript中的数组常用方法解析
2016/06/17 Javascript
js日期相关函数dateAdd,dateDiff,dateFormat等介绍
2016/09/24 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
详解Vuex中mapState的具体用法
2017/09/28 Javascript
vue实现点击隐藏与显示实例分享
2019/02/13 Javascript
解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题
2019/09/27 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:EE凭借法力虚空拿下4杀
2017/03/30 DOTA
[25:45]2018DOTA2亚洲邀请赛4.5SOLO赛 Sylar vs Paparazi
2018/04/06 DOTA
Python操作Mysql实例代码教程在线版(查询手册)
2013/02/18 Python
Python中几种属性访问的区别与用法详解
2018/10/10 Python
修改python plot折线图的坐标轴刻度方法
2018/12/13 Python
Python中的 ansible 动态Inventory 脚本
2020/01/19 Python
详解python中的异常和文件读写
2021/01/03 Python
雷朋巴西官方商店:Ray-Ban Brasil
2020/07/21 全球购物
个人简历的自荐信
2013/10/23 职场文书
恐龙的灭绝教学反思
2014/02/12 职场文书
家长学校工作方案
2014/05/07 职场文书
计算机网络专业求职信
2014/06/05 职场文书
见义勇为事迹材料
2014/12/24 职场文书
早会开场白台词大全
2015/06/01 职场文书
2015年村级财务管理制度
2015/08/04 职场文书
某药房的新员工入职告知书!
2019/07/15 职场文书