【问题标题】:PHP session is empty even when Session ID is right即使会话 ID 正确,PHP 会话也是空的
【发布时间】:2011-02-21 15:17:40
【问题描述】:

昨天我几乎搜索了所有关于 php 会话的主题,我查看了手册,它仍然没有用。因此我熬夜很晚。

场景是:我使用标准的 html 表单登录。我的会话填充了一些变量,并且工作正常。然后我使用 Flash uploadify 上传一些照片,并通过参数 - PHPSESSID。我的 php 脚本无法识别会话。它认为它是空的。然后我尝试与不同的客户端进行该会话,例如FirefoxOpera,它也是空的。然后我尝试使用不同的Chrome 选项卡进行该会话,并且它可以工作

如您所见,我唯一的保护是通过 IP。我不扫描其他东西,所以当通过良好的 PHPSESSID 并且客户端 IP 匹配时,无论客户端类型、版本等如何,这应该可以工作

这是init_session.php,我每次都包含在其他文件开头的文件。因此,我知道会话 ID 是通过 Flash 传递的。但是会话是空的。

目录设置在顶部,路径是直接的,所以应该没有任何问题。当保存路径为默认值时,它也不起作用。我还关闭了会话自动启动和会话仅使用 cookie。除了我需要手动设置 cookie 之外,它并没有改变什么。

这里有什么我可以尝试的吗?我想我已经没有选择了。

编辑:
我忘记了最重要的事情,我认为关闭 suhosin.session.cryptua 可以解决问题,但我无法使用 ini_set 将其关闭,还有其他方法吗?似乎这个选项使用用户代理字段加密会话就是这种情况。

ini_set('session.auto_start', '0');
ini_set('session.save_path','/public_html/nowy/tmp');

if (isset($_POST["PHPSESSID"])) {
    session_id($_POST["PHPSESSID"]);
} elseif (isset($_COOKIE['PHPSESSID'])) {
    session_id($_COOKIE["PHPSESSID"]);
} elseif (isset($_GET["PHPSESSID"])) {
    session_id($_GET["PHPSESSID"]);
} 
session_start();
setcookie("PHPSESSID", session_id(), time()+3600, "/");

if (!isset($_SESSION['user'])) {
$_SESSION['user'] = 0;
}

if (!isset($_SESSION['initiate'])) {
    session_regenerate_id();
    $_SESSION['initiate'] = true;
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}

echo ini_get('session.save_path').'<br />';

echo $_POST["PHPSESSID"];
print_r($_SESSION);

已解决

这个问题已经解决了。我无法将cryptua 设置为关闭,因为我需要复制原始的php5.ini 并替换一些变量以使其正常工作。

问题出乎意料suhosin.session.cryptua

【问题讨论】:

  • 嗯......当您只关注技术上必要的基础知识时,您可以初始化会话吗?如果是,那么描述症状时不要出现所有的迷雾,如果不是,则尝试一个接一个地添加技术细节,直到问题再次出现。
  • 正常的请求和uploadify发出的请求有什么区别?例如。您是否通过相同的主机名/子域请求脚本?
  • 请查看更新。我忘了提,但主要的不同是 user-agent 字段,因为其他浏览器也不起作用

标签: php ajax flash session


【解决方案1】:

正如弗罗德在他的评论中建议的那样,我将把这个作为答案。

这可能在使用 any flash 脚本时发生,而不仅仅是上传。除非用户代理字段相同,否则任何其他 Flash 上传器(例如 SWFUpload)都不会获得会话。

当您的服务器安装了suhosin 补丁时会发生这种情况,但似乎有时即使按照alecgorge 的建议启用设置suhosin.session.cryptua 也不会发生此问题。虽然我不相信这一点。当然,您可以使用 php 脚本将这个变量传递给 flash,以发现用户浏览器的用户代理,然后 flash 可以将自己伪装成同一个浏览器,但这不是优雅的解决方案,我不知道 actionscript,所以我不能说如果 flash真的可以做到。

非常重要: 实际上有两个设置可以修复这个安全补丁。

  1. suhosin.session.encrypt
  2. suhosin.session.cryptua

如果第一个被禁用,则会话根本不会加密,因此不会发生问题。不建议禁用此功能。如果我们只禁用第二个,那么会话将被加密,但加密不会在用户代理字段上中继。这意味着任何浏览器或 http 客户端都可以获取任何会话。因此建议放置一些其他的安全字段。 Suhosin 也可以处理会话 IP 保护,因此我建议启用 suhosin.session.cryptraddr。其他设置可以在这里找到:
Suhosin configuration

为了解决这个问题,我建议:

  1. 如果安装了 suhosin,请检查 phpinfo()。如果没有,则不会出现问题。
  2. 如果安装了 suhosin 并且启用了 suhosin.session.cryptuasuhosin.session.encrypt,则复制现有的和工作的 php.ini。它在 php 信息页面的顶部:Loaded Configuration File /public_html/php5.ini
  3. 创建您自己的 php.ini 并设置:
    • suhosin.session.encrypt = 开启
    • suhosin.session.cryptraddr = 开启
    • suhosin.session.cryptua = 关闭

【讨论】:

  • 请注意,使用启用 suhosin.session.cryptraddr 可能会中断某些代理后面的访问者的会话(一些公司代理在多个代理服务器之间平衡用户连接 [以非粘性方式],每个代理服务器都有不同的知识产权)。
【解决方案2】:

通常使用 Uploadify 我必须这样做:

$('#uploadify').uploadify('scriptData':{'session_name':'<?php echo session_id(); ?>'}});

在客户端与服务器端类似的东西结合使用:

if($_POST['session_name']) {
    session_id($_POST['session_name']);
}
session_start();

【讨论】:

  • 我当然会发送带有uploadify参数的会话ID。请阅读整篇文章并更新。我认为suhosin就是这样。
  • 哦,我读了整本书。只是这是一个非常常见的错误,当人们认为他们已经避免了这个陷阱时,他们往往会落入其中。将会话作为名为 PHPSESSID 的获取变量发送吗?尝试将其称为其他名称并像此处一样发布。然后删除为 PHPSESSID 抓取 post get 和 cookie 的东西。
  • 另外,我在打开suhosin.session.cryptua的服务器上使用它,我没有问题。
  • 因为其他浏览器也无法获取此会话。这一定是苏霍辛。然后我又不能把它关掉。一旦我弄乱了htaccess,就会发生内部服务器错误。 php.ini 根本不起作用。
猜你喜欢
  • 2011-08-30
  • 2014-04-24
  • 1970-01-01
  • 2011-04-05
  • 2014-07-31
  • 1970-01-01
  • 2019-10-28
  • 2017-12-13
  • 2014-08-14
相关资源
最近更新 更多