为什么 PHP 不读取通过 cookie 发送的会话 ID?



我正在将应用程序从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和其他谷歌结果

并尝试了以下补救措施,但无济于事:

  • 将 PHPerror_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的一部分提交给它的值是错误的。

最新更新