刷新时会重置Codeigniter会话

时间:2018-08-28 15:26:36

标签: php session codeigniter-3

一个月后,我试图解决这个问题,并尝试了所有相关问题的答案,我决定自己问这个问题。

此问题在我们最近购买的新服务器上发生,与在localhost和最后一台服务器上正常工作的代码相同。但这可能与代码有关。

正确创建了会话并设置了令牌,var_dump显示了这一点。但是,当用户尝试登录时,在重定向到访问功能后,未设置会话令牌,因此不会发生登录。

即使在同一页面上,如果刷新,则__ci_last_regenerate(获取上一次重新生成会话的时间)是当前时间,并且每次刷新后都会更改。

在var / lib / php / session中,每次刷新后都会创建两个不同的文件,不知道为什么。这是图片:

enter image description here

一个19秒的数据没有正确的数据(时间和令牌),最后一个只有时间。

此外,我们最近向网站添加了一个新的子域,因此我们在同一服务器上有两个不同的子域。

这是会话配置:

$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;

也尝试过使用DB驱动程序,它在表上生成了2条(有时是3行)。配置为:

$config['sess_driver']= 'database';
$config['sess_cookie_name']= 'ci_session';
$config['sess_expiration']= 0;
$config['sess_save_path']= 'ci_sessions';
$config['sess_match_ip']= FALSE;
$config['sess_time_to_update']= 300;
$config['sess_regenerate_destroy']= FALSE;
$config['sess_use_database']= TRUE;
$config['sess_expire_on_close']= TRUE;
$config['sess_table_name']= 'ci_sessions';

数据库的输出为其列(id,ip,时间戳,数据):

enter image description here

数据始终相同,在一种情况下,最后一次重新生成包含时间和令牌,而在另一种情况下,仅最后一次重新生成(每次刷新2行)。

PHP是7.2.7。 CodeIgniter是3.1.5。

如果需要,将提供任何其他所需的代码或服务器信息。

编辑4/9: 还应某些用户的要求添加这些cookie数据。

$config['cookie_domain']    = '.my-domain.com';
$config['cookie_path']      = '/';
$config['cookie_secure']    = FALSE;
$config['cookie_httponly']  = FALSE;

4 个答案:

答案 0 :(得分:1)

您似乎没有将会话数据存储在任何地方,而是存储在用户的Cookie中,因为您的配置似乎可以读取

class A {
    test(){}
  
    printA() {
        this.test();
        console.log('A');
    }      
}

const dummy = function(func){
    func.apply(this, []);
};

const a = new A();
dummy(a.printA.bind(a));

由于使用的是$config['sess_save_path'] = NULL; 驱动程序,因此应指定会话数据存储在服务器中的位置。默认情况下(开箱即用),CodeIgniter的设置如下:

files

您需要指定CodeIgniter可以写入的目录。否则,如果会话数据未存储在服务器中,则无论何时尝试执行任何操作,cookie中的会话都不会与任何内容匹配。

请记住,CI会话与本机PHP会话并不完全相同。

此外,正如CI本身在配置中指出的那样:

$config['sess_save_path'] = APPPATH . 'ci_session/';

更新(2018年8月31日)基于您对原始问题的更新:

使用数据库时,会话配置中有一些不需要/冗余的设置。这些都是您所需要的,您设置中的任何多余内容都将消失:

|   'sess_save_path'
|
|   The location to save sessions to, driver dependent.
|
|   For the 'files' driver, it's a path to a writable directory.
|   WARNING: Only absolute paths are supported!
|
|   For the 'database' driver, it's a table name.
|   Please read up the manual for the format with other session drivers.
|
|   IMPORTANT: You are REQUIRED to set a valid save path!

我认为不是这种情况,但是请检查您可能在调用本地$config['sess_driver'] = 'database'; $config['sess_cookie_name'] = 'ci_session'; $config['sess_expiration'] = 0; $config['sess_save_path'] = 'ci_sessions'; $config['sess_match_ip'] = FALSE; $config['sess_time_to_update'] = 300; $config['sess_regenerate_destroy'] = FALSE; 函数的任何地方的代码。这样做会使CI会话管理的行为无法预测,并且症状之一就是会话无法持续(我很难学到这一点,花了大约一个月的时间进行调试,直到发现一个单独的session_start调用将所有事情搞砸了)

您能检查会话表中的session_start()列是否正在实际写入吗? (以上的另一种症状)。尝试运行此命令,如果一切都返回为“空”,则我们可能会越来越近:

data

此外,请记住,仅创建会话表是不够的。您是否根据select case when cast(data as char(1000)) = '' then "empty" else "something" end as content, count(*) from ci_sessions group by content; 的设置运行了所需的ALTER

答案 1 :(得分:1)

-确保仅初始化一次会话库

$this->load->library('session');

-确保未自动加载

application/config/autoload.php

-如果您使用的是Codeigniter版本3,则不再需要与会话变量有任何关系时,请致电session_write_close()

-确保您既没有unset( $_SESSION );也没有销毁它

session_destroy();

// or

$this->session->sess_destroy();

-会话受这些Cookie配置application/config/config.php

的影响
$config['cookie_domain']    = '.your-domain.com';
$config['cookie_path']      = '/';

答案 2 :(得分:0)

如果您使用的是http服务器,请设置config_secure = false,否则您的会话将在每次刷新页面时过期

在下面检查

   $config['cookie_prefix'] = '';
   $config['cookie_domain'] = '';
   $config['cookie_path'] = '/';
   $config['cookie_secure'] = FALSE;
   $config['cookie_httponly']   = FALSE;

答案 3 :(得分:0)

好的,问题在于我们的Centos 7中有两个子域的Apache conf。

我们在同一个httpd conf文件中都有两个VirtualHost数据。解决方法是为每个域创建一个不同的conf文件。像这样:

domain1.com.conf

<VirtualHost *:80>
  ServerName domain1.com
  ServerAlias domain1
  DocumentRoot /var/www/html/domain1
  ErrorLog /var/log/httpd/domain1-error_log
  CustomLog /var/log/httpd/domain1-access_log combined
</VirtualHost>

与domain2相同。

希望这可以帮助任何人。