CI中session的过期时间

最近发现项目中有些页面刷新后会更新session过期时间,有些则不会,很是诡异。

我的理解是,用户每次请求页面时,都应该重置session过期时间=time() + session life time, 但是CI并不是这样做。

先说下对CI session的理解,以下是CI session的配置项:

参数 默认值 选项 描述
sess_driver files files/database/redis/memcached/custom 使用的存储 session 的驱动
sess_cookie_name ci_session [A-Za-z_-] characters only session cookie 的名称
sess_expiration 7200 (2 hours) Time in seconds (integer) 你希望 session 持续的秒数 如果你希望 session 不过期(直到浏览器关闭),将其设置为 0
sess_save_path NULL None 指定存储位置,取决于使用的存储 session 的驱动
sess_match_ip FALSE TRUE/FALSE (boolean) 读取 session cookie 时,是否验证用户的 IP 地址 注意有些 ISP 会动态的修改 IP ,所以如果你想要一个不过期的 session,将其设置为 FALSE
sess_time_to_update 300 Time in seconds (integer) 该选项用于控制过多久将重新生成一个新 session ID 设置为 0 将禁用 session ID 的重新生成
sess_regenerate_destroy FALSE TRUE/FALSE (boolean) 当自动重新生成 session ID 时,是否销毁老的 session ID 对应的数据 如果设置为 FALSE ,数据之后将自动被垃圾回收器删除
这里要说的是 sess_time_to_update ,这个配置项的意思是:每过一段时间(默认是300s) , 会将同一个会话的sessionid替换成另一个sessionid,会话仍保持有效(不改变登录状态)。也就是说,在2小时的session有效期内,sessionid每隔300s都会更新一次,会话状态不变。

后来对比了一下刷新页面更新session过期时间的页面 和 不更新session过期时间的页面,发现更新session过期时间的页面不仅发起get页面的请求,还发送了另一个ajax请求。system/libraries/Session/Session.php有一段代码:

session_start();

		// Is session ID auto-regeneration configured? (ignoring ajax requests)
		if ((empty($_SERVER['HTTP_X_REQUESTED_WITH']) OR strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest')
			&& ($regenerate_time = config_item('sess_time_to_update')) > 0
		)
		{
			if ( ! isset($_SESSION['__ci_last_regenerate']))
			{
				$_SESSION['__ci_last_regenerate'] = time();
			}
			elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time))
			{
				$this->sess_regenerate((bool) config_item('sess_regenerate_destroy'));
			}
		}
		// Another work-around ... PHP doesn't seem to send the session cookie
		// unless it is being currently created or regenerated
		elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id())
		{
			setcookie(
				$this->_config['cookie_name'],
				session_id(),
				(empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime']),
				$this->_config['cookie_path'],
				$this->_config['cookie_domain'],
				$this->_config['cookie_secure'],
				TRUE
			);
		}

可以看到,对于非ajax,且session未过期的请求,是不会更新session过期时间的,只会更新 __ci_last_regenerate(如果session用文件保存,这个值会保存在session文件中),用于更新sessionid.

而对于未过期session的ajax请求,每次都会根据当前时间更新session的过期时间 。

这才导致了刷新页面时不更新session过期时间。很奇怪为什么CI要这么做。

你可能感兴趣的:(php)