文档章节

codeigniter 3 SESSION的实现(基于redis)

o0无忧亦无怖
 o0无忧亦无怖
发布于 2015/10/12 16:23
字数 1372
阅读 623
收藏 11
点赞 1
评论 0

###CI 2 SESSION的诟病 相信无数人在使用CI2的Session类库时,遇到各种的坑,各种抱怨,各种不解。在CI中国论坛能搜到大量关于Session类库的提问,说明要想用好session类库还是得下一番功夫。 ####Session和cookie的区别 在某些语境中,cookie是session的一种实现方式,Ci 2的类库设计似乎就这么认为的。于是,产生了CI2中COOKIE即SESSION的说法。在安全性方面,CI 2当然也由考虑,COOKIE是经过加密过的,而且一旦修改,服务器便不再识别。

**CI 2的session工作原理 **

CI 2提供了一个元数据,我们可以把这个元数据看为一个自定义的验证机制,其包含以下内容:

Array
(
    [session_id] => 4a5a5dca22728fb0a84364eeb405b601
    [ip_address] => 127.0.0.1
    [user_agent] => Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7;
    [last_activity] => 1303142623
)

其中Session id是重要的,Session id不对,直接拒绝。 验证选项在配置文件里有规定,(IP地址的限制)(user agent限制)(上次活动时间)等

$config['sess_match_ip']  = FALSE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update'] = 300;

特别是当设置sess_match_useragent设为TRUE时,会遇到各种的坑: 你用flash组件上传文件,只有登录的用户才能上传文件,结果你每次判断用户是否登录都会出错,因为flash发送的http请求有可能更改了user agent; 使用ie切换不同的模式,比如兼容模式,也会造成user agent不同; user agent的长度最长是120个字符,手动设置User agent是需要截取字符到最大120个。 另外,如果出现“Cannot modify header information - headers already sent by”错误,基本可以断定是你文件的编码格式有误,请去掉bom头。

####安全问题

CI使用cookie来传递数据本来就不够安全,而且如果数据量巨大时也会有性能问题。但是CI还是友好地加入以下几个安全验证机制:

加密令牌

$config['encryption_key'] = 'mahuaz_';
$config['sess_encrypt_cookie'] =  TRUE;

设置后,客户端检查cookie时就可以看到加密后的序列化数据。

自动更新机制

CI默认每五分钟更新一次令牌,更新发生在客户端的一次请求中。客户端每发送一次请求,会把cookie的信息发送到服务器,服务器根据发来的cookie判断是否到了应该更换令牌的时间了,如果是,就会重新换一个新的令牌返回给客户端。这就相当于门卫给你换了令牌,下次要使用新令牌进门。此时即使有坏人伪造了一个令牌也不起作用了,因为旧令牌已经作废。这样就相当于加了一条安全机制。可以使用:

$config['sess_time_to_update'] = 300;

来设置多长时间来换一次令牌。这个时间不要设置的太短,更新频繁也会影响性能。这里不要和sess_expiration混淆:

$config['sess_expiration']  = 7200;

这个配置是用来指示整个cookie的过期时间的,相当于令牌完全失效,再怎么更换都不起作用。

###CI 3的变更 CI3的Session的重大改变就是默认使用了原生的Session,这符合Session类库本来的意思,似乎更加合理一些。总体来说,虽然设计理念不同,但为了保证向后兼容性,类库的使用方法与CI2.0的差别不是很大。一般的使用过程是这样的:

截取一段CI2 SESSION的代码:

         if ($this->sess_encrypt_cookie == TRUE)
                {
                        $this->CI->load->library('encrypt');
                }

                if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')
                {
                        $this->CI->load->database();
                }


                $this->now = $this->_get_time();

  
                if ($this->sess_expiration == 0)
                {
                        $this->sess_expiration = (60*60*24*365*2);
                }


                $this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;


截取一段CI3 SESSION的代码:

	$class = $this->_ci_load_classes($this->_driver);

		// Configuration ...
		$this->_configure($params);

		$class = new $class($this->_config);
		if ($class instanceof SessionHandlerInterface)
		{
			if (is_php('5.4'))
			{
				session_set_save_handler($class, TRUE);
			}
			else
			{
				session_set_save_handler(
					array($class, 'open'),
					array($class, 'close'),
					array($class, 'read'),
					array($class, 'write'),
					array($class, 'destroy'),
					array($class, 'gc')
				);

				register_shutdown_function('session_write_close');
			}
		}
		else
		{
			log_message('error', "Session: Driver '".$this->_driver."' doesn't implement SessionHandlerInterface. Aborting.");
			return;
		}

可以看到CI 3已经完全重写了SESSION,由不同的驱动器用来保存SESSION(并且淘汰了COOKIE)。

###CI3 SESSION FOR REDIS 在配置文件中,CI 3的配置也完全缩减了很多

$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = NULL;
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;

CI 3 可以配置驱动器类型,包括files, database, redis, memcached以及自定义,$config['sess_driver'] 来配置驱动器,默认的驱动器是files。官方推荐用files类型(在一般情况下) 配置session save path 配置节sess_save_path会根据不同的驱动器,定义不同。 为了适用redis,我这里将他配置为

tcp://127.0.0.1:6379

在上面的代码中,有下面这两句

$class = new $class($this->_config);
		if ($class instanceof SessionHandlerInterface){
...
}

确立了$_SEESION 由 redis进行存储,加载的类是Session_redis_driver(位于sytstem/libraries/Session_redis_driver),在测试控制器中, 我们写一些测试代码:

    $_SESSION['test'] = 'There is test!';
    var_dump($_SESSION);

会打印出

array(2) { ["__ci_last_regenerate"]=> int(1444637502) ["test"]=> string(13) "There is test" } 

我们在Session_redis_driver的read方法中写到

var_dump($this->_key_prefix.$session_id);  //redis  key的值,由_key_prefix.$session_id组合构成

会打印出

string(51) "ci_session:23ea4298dc5e7d6b808ca70ddb1665590e5cfb58"

为了测试redis,我们可以在PHP中测试:

$redis = new redis();
$redis->connect('127.0.0.1',6379);
var_dump($redis->get("ci_session:23ea4298dc5e7d6b808ca70ddb1665590e5cfb58"));

会打印出

string(60) "__ci_last_regenerate|i:1444637502;test|s:13:"There is test";"

同样,我们在redis-cli中输入

get ci_session:23ea4298dc5e7d6b808ca70ddb1665590e5cfb58

会打印出

__ci_last_regenerate|i:1444637502;test|s:13:"There is test

至此,CI 3 使用REDIS作为SESSION存储就分析完毕了

© 著作权归作者所有

共有 人打赏支持
o0无忧亦无怖
粉丝 33
博文 73
码字总数 49253
作品 1
程序员
使用CodeIgniter框架搭建RESTful API服务

使用CodeIgniter框架搭建RESTful API服务 发表于 2014-07-12 | 分类于 翻译笔记 | 6条评论 在2011年8月的时候,我写了一篇博客《使用CodeIgniter框架搭建RESTful API服务》,介绍了RESTful的...

thinkyoung ⋅ 2015/08/07 ⋅ 0

CodeIgniter中运用composer安装依赖包

基本信息 + CodeIgniter 版本:3.1.8+ Nginx: Tengine/2.1.2 (nginx/1.6.2)+ MySQL: Ver 14.14 Distrib 5.6.33, for Linux (x86_64) using EditLine wrapper+ PHP: 5.6.30+ Zend Engine ......

冷三叔 ⋅ 04/28 ⋅ 0

Windows10环境下Codelgniter安装及配置说明

CodeIgniter ,简称CI,是一套给 PHP 网站开发者使用的应用程序开发框架和工具包。 它的目标是让你能够更快速的开发,它提供了日常任务中所需的大量类库, 以及简单的接口和逻辑结构。通过减...

Yuanmes ⋅ 05/02 ⋅ 0

Laradock 7.0.2 发布,Docker 的 PHP 本地开发环境

Laradock 7.0.2 已发布,更新内容如下: 更新 Kibana 版本以匹配 Elasticsearch 的版本; 修复 php 5.6 drush “Segmentation fault” 报错; 修复 php 7.0 swoole 构建失败。 更多细节可查阅...

王练 ⋅ 06/20 ⋅ 0

CodeIgniter的伪静态配置

基本信息 + CodeIgniter 版本:3.1.8+ Nginx: Tengine/2.1.2 (nginx/1.6.2)+ MySQL: Ver 14.14 Distrib 5.6.33, for Linux (x86_64) using EditLine wrapper+ PHP: 5.6.30+ Zend Engine ......

冷三叔 ⋅ 04/28 ⋅ 0

PHP 开源网站管理系统 - POSCMS

POSCMS 介绍 PHP 开源网站管理系统(PhpOpenSourceCMS,简称POSCMS)以开放、开源、灵活为产品理念,基于 PHP+MYSQL+CI 框架开发的开源 Web 内容管理系统,程序完美兼容 PHP7 ,并在 PHP7 基...

天睿云计算 ⋅ 2017/05/19 ⋅ 1

POSCMS V3.2.18 发布,跨平台网站内容管理系统

POSCMS V3.2.18 已发布,PHP开源内容管理系统(PhpOpenSourceCMS简称POSCMS)是Php+Mysql开发的一款开源的跨平台网站内容管理系统。POSCMS系统基于CodeIgniter框架,具有良好扩展性和管理性。...

天睿云计算 ⋅ 04/24 ⋅ 0

php-Codeigniter使用redis

1、安装redis 首先计算机上必须已经装了redis服务(redis数据库)并运行,详见另一篇文章:http://blog.csdn.net/wzj0808/article/details/54891178 2、安装phpredis <1>下载 项目地址:htt...

梦梦阁 ⋅ 06/06 ⋅ 0

php基于thinkphp、smarty\CodeIgniter构建的开源的淘宝客cms程序下载

现在有很多开源的淘宝客软件cms,很多人不知道,所以,提供该服务,完全开源,比市面上的加密的好很多, 这些开源的淘宝客程序代码写的都非常简约,适合学习观摩,所以,收集了一些优秀的开源...

616921521 ⋅ 05/30 ⋅ 0

Yaf 中使用 Larvael Eloquent ORM

本教程示例代码见:https://github.com/creazy412/yaf2eloquentorm 背景介绍 Yaf 是鸟哥(Laruence)在俩年前写的一个PHP扩展的MVC框架. 开发Yaf的目的是为了解决使用框架带来的性能下降的经...

老K8 ⋅ 05/31 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

在java中读取文件(也支持读取jar中的文件)

getClass().getResourceAsStream("文件名.格式"); 这个方法是用于获取当前类所在目录下的文件;需要将文件放到和当前类同一个包下面 比如我有个类在 com.test这个包下, 要读取一个test.jpg的图...

太黑_thj ⋅ 51分钟前 ⋅ 0

CentOS 7 源码编译安装 MySQL 5.7记录

没事瞎折腾,本来可以yum安装,却偏偏去要编译源码。 1. 安装依赖包 1). 安装cmake等依赖 # yum install cmake ncurses ncurses-devel bison bison-devel 2). 安装boost 1.59.0 # wget htt...

admin_qing ⋅ 53分钟前 ⋅ 0

tcp/ip详解-链路层

简介 设计链路层的目的: 为IP模块发送和接收IP数据报 为ARP模块发送ARP请求和接收ARP应答 为RARP模块发送RARP请求和接收RARP应答 TCP/IP支持多种链路层协议,如以太网、令牌环往、FDDI、RS-...

loda0128 ⋅ 今天 ⋅ 0

spring.net aop代码例子

https://www.cnblogs.com/haogj/archive/2011/10/12/2207916.html

whoisliang ⋅ 今天 ⋅ 0

发送短信如何限制1小时内最多发送11条短信

发送短信如何限制1小时内最多发送11条短信 场景: 发送短信属于付费业务,有时为了防止短信攻击,需要限制发送短信的频率,例如在1个小时之内最多发送11条短信. 如何实现呢? 思路有两个 截至到当...

黄威 ⋅ 昨天 ⋅ 0

mysql5.7系列修改root默认密码

操作系统为centos7 64 1、修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不对密码进行验证 2、重启 mysqld 服务:systemctl restart mysql...

sskill ⋅ 昨天 ⋅ 0

Intellij IDEA神器常用技巧六-Debug详解

在调试代码的时候,你的项目得debug模式启动,也就是点那个绿色的甲虫启动服务器,然后,就可以在代码里面断点调试啦。下面不要在意,这个快捷键具体是啥,因为,这个keymap是可以自己配置的...

Mkeeper ⋅ 昨天 ⋅ 0

zip压缩工具、tar打包、打包并压缩

zip 支持压缩目录 1.在/tmp/目录下创建目录(study_zip)及文件 root@yolks1 study_zip]# !treetree 11└── 2 └── 3 └── test_zip.txt2 directories, 1 file 2.yum...

蛋黄Yolks ⋅ 昨天 ⋅ 0

聊聊HystrixThreadPool

序 本文主要研究一下HystrixThreadPool HystrixThreadPool hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java /** * ThreadPool used to executed {@link Hys......

go4it ⋅ 昨天 ⋅ 0

容器之上传镜像到Docker hub

Docker hub在国内可以访问,首先要创建一个账号,这个后面会用到,我是用126邮箱注册的。 1. docker login List-1 Username不能使用你注册的邮箱,要用使用注册时用的username;要输入密码 ...

汉斯-冯-拉特 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部