我正在将应用程序从CodeIgniter 2.2.1升级到3.1.8。应用程序对用户进行身份验证并将身份验证状态保存在会话中,并在升级后中断,以便用户无法再登录。我正在Linux虚拟机上通过nginx上的PHP-FPM运行PHP版本7.1.12。
我花了 1.5 天的大部分时间试图深入了解这一点。据我所知,它归结为PHP不读取浏览器通过cookie发送的会话ID,并为每个请求创建一个新的会话(和会话ID(。我可以从请求 cookie 的ci_session
值与相应响应 cookie 中的ci_session
值不同(如 Firefox devtools 中显示的(以及每次都会创建一个新文件的事实中看出这一点。(我已经将CodeIgniter配置为使用文件驱动程序。
在尝试调试时,如果我在调用session_start()
之前记录session_id()
的值(在/system/libraries/Session/Session.php
中,第 143 行(,我只会看到一个空白字符串。紧接着,我看到Firefox在响应cookie中显示的相同新会话ID。
我已经相当广泛地阅读了:
- CI3 升级指南
- PHP 会话文档
- Stackoverflow和其他谷歌结果
并尝试了以下补救措施,但无济于事:
- 将 PHP
error_reporting
设置为E_ALL
并检查 PHP 错误日志中是否有任何消息,例如与已经输出的标头相关的消息 - 将
$config['encryption_key']
的值更改为从 http://randomkeygen.com/的 CodeIgniter 部分复制的随机 32 个字符的字符串 - 将
$config['sess_cookie_name']
的值更改为仅由小写字母数字字符组成的字符串 - 确保确实在
$config['sess_save_path']
目录中创建了会话文件,具有正确的ID和信息 - 尝试将
$config['cookie_domain']
设置为.domainname.tld
(也只是''
(
直接跳到 CI 3.1.8 - (我最初升级到 3.0.0,并计划浏览每个版本的升级说明,直到 3.1.8。我还没有这样做,相反,我只是用 3.1.8 版本替换了
/system
文件夹(。
下面我粘贴了我认为是 CI 和 PHP 的所有相关设置。显然,我错过了一些东西,很可能是一些非常基本的东西。如何进一步诊断/修复?
代码点火器设置
$config['cookie_prefix'] = "";
$config['cookie_domain'] = "";
$config['cookie_path'] = "/";
$config['cookie_secure'] = FALSE;
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 3600 * 24 * 60; // 60 days
$config['sess_use_database'] = FALSE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_driver'] = 'files';
$config['sess_save_path'] = BASE . 'storage/session';
PHP设置
Session Support enabled
Registered save handlers files user
Registered serializer handlers php_serialize php php_binary wddx
Directive Local Value Master Value
session.auto_start Off Off
session.cache_expire 180 180
session.cache_limiter nocache nocache
session.cookie_domain no value no value
session.cookie_httponly Off Off
session.cookie_lifetime 0 0
session.cookie_path / /
session.cookie_secure Off Off
session.gc_divisor 1000 1000
session.gc_maxlifetime 1440 1440
session.gc_probability 1 1
session.lazy_write On On
session.name PHPSESSID PHPSESSID
session.referer_check no value no value
session.save_handler files files
session.save_path /var/opt/remi/php71/lib/php/session /var/opt/remi/php71/lib/php/session
session.serialize_handler php php
session.sid_bits_per_character 5 5
session.sid_length 26 26
session.upload_progress.cleanup On On
session.upload_progress.enabled On On
session.upload_progress.freq 1% 1%
session.upload_progress.min_freq 1 1
session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix upload_progress_ upload_progress_
session.use_cookies On On
session.use_only_cookies On On
session.use_strict_mode Off Off
session.use_trans_sid 0 0
您描述的问题通常是错误的$config
项目设置。
您需要转到从 2.2.x 升级到 3.0.x 文档并逐步完成它。步骤 6 讨论需要执行哪些操作来更新会话使用情况。在我看来,您正在使用 v2.x 会话$config
项目。与会话相关的$config
发生了重要更改。首先看看这些。其中一个主要问题是确保正确设置$config['base_url']
。那里的不良值会产生各种不良副作用。
您可能需要查看 3.0.0 和当前版本之间的每个"升级"文档,以查看是否有任何可能影响您站点的内容。除了替换大多数版本的系统文件夹之外,没有太多的"步骤"。在 v3.0.0 之后,我记得没有影响会话的内容。但是有一些重要的项目需要注意。
有关确定会话是否正常工作的帮助,请查看 GitHub 上的这个简单存储库。
有时这个问题,当使用'files'
驱动程序时,可能是权限问题。但是,当您看到正在创建的文件时,事实并非如此。
好的,我最终解决了这个问题。我不确定解决方案是什么,但我所做的修复它的最终更改是从我的浏览器中清除与该站点相关的所有 cookie,注意到$_COOKIE
超全局不包含ci_session
条目($config['sess_cookie_name']
中配置的 cookie 的名称(,尽管它显示在 Firefox devtools 中显示的浏览器请求中。
一路走来,我还:
- 从 PHP 7.1 升级到 PHP 7.2
- 删除了两个 CI 2.2 时代已弃用的会话设置(特别是
$config['sess_use_database']
和$config['sess_table_name']
( - 添加了 CI 3.1.8 中提供的新设置,可能还有更早的版本 (
$config['sess_regenerate_destroy'] = FALSE;
(
顺便说一句,我还注意到session_id()
在调用session_start()
之前不返回任何内容,即使会话正常工作(并且$_COOKIE
中存在正确的ci_session
值(。因此,我将session_id()
返回的空白字符串解释为表示PHP无法读取作为cookie的一部分提交给它的值是错误的。