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

时间:2018-05-02 19:41:15

标签: php codeigniter session cookies

我正在将应用程序从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_id()之前记录session_start()的值(/system/libraries/Session/Session.phpline 143),我只会看到一个空字符串。紧接着,我看到Firefox在响应cookie中显示的新会话ID。

我通过以下方式进行了相当广泛的阅读:

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

  • 将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的所有相关设置。很明显我错过了一些东西,很可能是一些非常基本的东西。如何进一步诊断/修复?

CodeIgniter设置

$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

2 个答案:

答案 0 :(得分:1)

您描述的问题通常是错误的$config项设置。

您需要转到Upgrading from 2.2.x to 3.0.x文档并逐步完成。 Step 6讨论了更新会话使用情况需要做些什么。在我看来你正在使用v2.x session $config项。与会话相关的$config有重大更改。先看看那些。其中一个主要方面是确保$config['base_url']设置正确。一个坏的价值有各种不好的副作用。

您可能希望查看3.0.0与当前版本之间的每个“升级”文档,以查看是否存在可能影响您网站的任何内容。除了替换大多数版本的系统文件夹之外,没有太多的“步骤”。超越v3.0.0,我无法记住影响会话。但是还有一些重要的事项要处理。

有关确定会话是否正常工作的帮助,请查看此简单repository on GitHub

有时这个问题,当使用'files'驱动程序时,它可能是权限问题。但是当你看到创建的文件不是它时。

答案 1 :(得分:0)

好的,我最终解决了这个问题。我不确定解决方案是什么,但我做出的最后修改是通过我的浏览器清除与网站相关的所有cookie,注意到$_COOKIE超全球没有包含{{{1}的条目1}}(ci_session中配置的cookie的名称),尽管它出现在Firefox devtools中显示的浏览器请求中。

一路上,我也是:

  • 从PHP 7.1升级到PHP 7.2
  • 删除了两个CI 2.2时代已弃用的会话设置(具体为$config['sess_cookie_name']$config['sess_use_database']
  • 添加了CI 3.1.8中存在的新设置,以及可能的早期版本($config['sess_table_name']

顺便说一句,我还注意到$config['sess_regenerate_destroy'] = FALSE;在调用session_id()之前没有返回任何内容,即使会话正常工作({{1}中存在正确的session_start()值}})。所以我错误地解释了由ci_session返回的空字符串,这表示PHP无法读取作为cookie的一部分提交给它的值。