【问题标题】:PHP sessions working very well, but something's bugging me…PHP 会话运行良好,但有些东西困扰着我……
【发布时间】:2011-07-23 16:43:41
【问题描述】:

我一直在使用 PHP 会话,一切正常,完全符合我的需要。

然后我开始进一步研究潜在的安全问题并发现:

http://phpsec.org/projects/guide/4.html

请注意,所有用于确定现有会话或新会话“状态”的是:

session_start();

...然而这种事情我以前见过很多次:

<?php
if (isset($PHPSESSID))
{
    session_start($PHPSESSID);
}else{
    session_start();
};
?>

我曾假设这将允许在第二次调用时进行一些其他处理,或者它的逻辑允许会话以相同的会话 ID 重新启动,例如用于不同的页面。

但是我已经认为普通的session_start() 已经具有确定会话是否已在其他地方建立的逻辑,因为它“知道”保留现有的会话 ID 而不是发出新的 ID,除非它当然需要!

所以我测试了上述内容,但我根本无法让它工作。

<?php
if (isset($PHPSESSID))
{
        $oldsession = "On";
        $newsession = "Off";
        session_start($PHPSESSID);
}
    else
{

    session_start();
    $newsession = "On";
    $PHPSESSID = session_id( );

};

            echo 'ClientSessionID : '.$PHPSESSID.'<br>';
            echo 'Refreshed Session : '.$oldsession.'<br>';
            echo 'New Session : '.$newsession.'<br>';      
?>

要么我遗漏了一些东西,要么这个代码永远无法工作。即使会话被保留,$oldsession 也不会被回显。我得出结论,$PHPSESSID 上的测试永远不会奏效。

所以我的问题是:假设示例测试代码在语法上是正确的,在调用 session_start() 之前尝试预先确定会话“状态”是否合理?如果是这样,你会怎么做?

正如文章继续表明的那样,在会话开始后使用(假设的)生成的会话变量是向不同方向发送代码的唯一方法,所以我认为这实际上是唯一的方法它。

【问题讨论】:

  • 代码中的 else 块永远不会执行,因为 $PHPSESSID 的定义不会在页面刷新之间持续存在。
  • Else 确实执行了,因为变量不会持续存在,即测试因您所说的原因而失败。
  • 你是对的。我认为这就是 Dae 的意思,但只是误会了。
  • 是的,谢谢 Wiseguy,很抱歉造成混乱。

标签: php session


【解决方案1】:

看起来这篇文章写于 2005 年初,所以文章可能假设 register_globals 设置已打开。在 PHP4 的早期版本中,默认开启,但在 PHP5 中默认关闭。

要使您的代码正常工作,您需要明确使用 $_GET['PHPSESSID']$_COOKIE['PHPSESSID'],因为全局变量 $PHPSESSID 可能由于 register_globals 被禁用而未设置。

另外,请注意会话名称并不总是“PHPSESSID”。这是默认设置,但可以在 session.name server setting 中更改或在运行时使用 session_name() 在代码中更改。

【讨论】:

    【解决方案2】:

    session_start() 将回收一个活动会话(如果存在)。您可以使用以下 sn-p 观察此行为:

    <?php
    
    session_start();
    
    echo 'Current session ID: ' . session_id();
    
    $_SESSION['previous_id'] = session_id();
    session_regenerate_id();
    
    echo '<br />Session ID on next execution: ' . session_id();
    
    if(isset($_SESSION['previous_id'])) 
      echo '<br />Session ID on previous execution: ' . $_SESSION['previous_id'];
    
    ?>
    

    Wiseguy 说了其余的。

    【讨论】:

      【解决方案3】:

      您的 if(isset($PHPSESSID)) 没有检查您的想法。我不确定手头的语法......但试试这个:

      <?php
      if (isset(session_id($PHPSESSID)))
      {
              $oldsession = "On";
              $newsession = "Off";
              session_start($PHPSESSID);
      }
          else
      {
      
          session_start();
          $newsession = "On";
          $oldsession = "None";
          $PHPSESSID = session_id( );
      
      };
      
                  echo 'ClientSessionID : '.$PHPSESSID.'<br>';
                  echo 'Refreshed Session : '.$oldsession.'<br>';
                  echo 'New Session : '.$newsession.'<br>';      
      ?>
      

      我还向 $oldsession 添加了一个值,以便您可以看到 $PHPSESSID 未“设置”。

      希望有帮助!

      祝你好运!

      【讨论】:

      • 我不认为session_id() 会起作用,除非你已经打电话给session_start()
      • Wiseguy 在他的新评论中有它: if(isset($_COOKIE['PHPSESSID']) || isset($_GET['PHPSESSID'])) { //etc... 而不是上面提出的 isset(session_id($PHPSESSID))... 这就是我想要达到的目标。
      【解决方案4】:

      感谢 Dae 和 Wiseguy,你的回答给了我需要的提示,尽管你没有提到的是安全方面,这让我想到了这个主题。

      在上下文中,我所看到的示例无疑是从 register_globals 默认“打开”时的遗留代码,并且显然没有更新。

      代码现在无法运行的原因是 regsiter_globals 出于安全原因已在 PHP 中作为默认设置关闭。从 5.3.0 开始,它已被弃用,我正在使用 5.3.4

      我正在查看的安全问题是一种确定正在使用会话的用户是否是原始用户而不是欺骗他们会话的用户的方法,并且某些信息(IP 地址)可以在标题中获得甚至在您决定开始会话之前。

      但我现在知道 IP 地址也可以被欺骗,因此我认为首先启动会话并在之后验证(恢复任何以前设置的会话变量)。

      和原文章一样!

      【讨论】:

      • 代码 可以 现在可以使用,但您必须签入 $_COOKIE['PHPSESSID']$_GET['PHPSESSID'] 而不是 $PHPSESSID,正如我在回答中所说的那样。 // 会话劫持通常是在没有 IP 欺骗的情况下完成的,因此清除它们仍然没有什么坏处。所以我仍然认为事先进行验证是有好处的。但你是对的——如果他们也欺骗了 IP,那么你就不走运了。 // 另外,IMO,我们彻底回答了您提出的问题。您问如何使该代码工作,我告诉您如何使其工作以及为什么它最初没有工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多