【问题标题】:Having two different sessions in same domain在同一个域中有两个不同的会话
【发布时间】:2009-08-28 18:07:42
【问题描述】:

我经营 foo.com。我在 foo.com 中有两个不同的应用程序:一个是 foo.com/bar,另一个是 foo.com/example。我在用户登录时使用会话来跟踪有关用户的信息,但是如果用户从 foo.com/bar 转到 foo.com/example,则 foo.com/example 会看到用户从 foo.com/ 启动的会话栏并使用该信息。我的问题是,我怎样才能让每个目录同时进行两个不同的会话?

【问题讨论】:

标签: php


【解决方案1】:

您应该在调用 session_start 之前调用session_name。这将设置用于标识会话的 cookie 的名称(默认为 PHPSESSID)。

为每个应用程序使用不同的名称。您不必弄乱会话中的变量。

【讨论】:

  • +1:这确实是保持应用程序会话分离的最佳方式。
  • 将它们分开的最佳解决方案。给予 +1
【解决方案2】:

我认为强调与迄今为止提供的解决方案相关的潜在安全影响非常重要。 我从事 Web 应用程序渗透测试员已有大约 5 年的时间,在此期间开发了许多易受攻击的安全应用程序,以协助培训初级 IT 安全性。

我刚刚测试了所提供的解决方案,并注意到它们都不会阻止访问属于相邻应用程序的会话。通过 session_name() 使用不同的会话标识符名称不会阻止用户使用这些标识符的值。 PHP 没有为每个会话标识符名称单独存储。我有两个应用程序使用不同的会话名称并为浏览器设置 cookie 路径。 HTTP 响应中包含以下各自的 Set-Cookie 指令:

Set-Cookie: TESTONE=<value one>; path=/testone/

Set-Cookie: TESTTWO=<value two>; path=/testtwo/

如果两个应用都有完全不同的用户,并且某人只能访问 /testtwo/ 应用,则他们可能能够访问 /testone/ 应用上的信息,具体取决于处理会话参数的方式。下面的示例代码段显示了潜在的数据泄露,假设两个应用在成功验证后都使用$_SESSION["authenticated"] 参数。

<?php 
    session_name("TESTONE");
    ini_set("session.cookie_path","/testone/");
    session_start();
    if ($_SESSION["authenticated"] == "yes")
        echo $topsecretinfo;
?>

要访问这个$topsecretinfo,只需在/testtwo/ 应用程序上进行身份验证,在向/testone/ 申请。 PHP 的会话查找过程除了解析对应的值外,不识别会话标识符的名称。即“agcy648dja6syd8f93”的会话标识符值将返回相同的会话对象,而不管用于引用它的名称。

【讨论】:

    【解决方案3】:

    您也许可以使用session_set_cookie_params 设置要保存的会话的域和文件夹。即:

    // Used on foo.com/example
    session_set_cookie_params(86400, '/example');
    
    // Used on foo.com/bar
    session_set_cookie_params(86400, '/bar');
    

    【讨论】:

    • 这似乎不起作用;我以前(现在又一次)尝试过,但没有成功。这可能与我的全局 php.ini 设置有关。
    • 您需要在路径后面添加反斜杠。没有它肯定行不通。
    • 如果您可以访问 php.ini,您可以尝试直接设置 'session.cookie_path ' 参数,因为这就是该函数应该覆盖的内容。如果您无权访问 php.ini 文件,也可以使用 ini_set()。
    • 根据comments on php.net,“如果你想使用session_set_cookie_params(),你必须先使用session_name()...否则它将不起作用,不会给出任何错误,并且没有任何内容文档(无论如何我已经看过)将解释原因。”我还没有验证这一点。
    【解决方案4】:

    您也可以使用相同的会话,但更改您要查找的变量名称。

    编辑:抱歉,这没有回答您的问题,但提供了替代解决方案。

    【讨论】:

    • 这似乎是最好的解决方案。谢谢。
    • 谢谢 Matthew:如果它回答了您的问题,请记住将其标记为“答案”:)
    • 投票最多的答案更好 - 最好的方法是使用“session_name”。
    【解决方案5】:

    另一种解决方案是通过将来自 foo.com/bar 的所有会话值预先添加“bar_”和 foo.com/example 带有“example_”来有效地在会话中创建命名空间。

    避免这种乏味的方法是将此功能抽象为函数或类方法。例如:

    function set_session_value($key, $value) {
    
      //figure out which prefix to use by checking the current working 
      //directory, or whatever method you like. set $prefix equal to
      // "bar_" or "example_".
    
      $_SESSION[$prefix . $key] = $value;
    }
    

    然后使用匹配函数获取您的值。

    这样做的主要优点是您在 /bar 中编程时不必考虑在 /example 中使用的变量名称。另一个是,如果您决定更改存储会话值的方式,您可以轻松地在一个地方更改所有内容。

    【讨论】:

      【解决方案6】:

      我知道这是旧的,但认为它可能对某人有所帮助。这个例子展示了我们如何为我们的管理区域设置一个单独的会话。

      if ( $_SERVER['REQUEST_URI'] == '/admin/' ):
          $session_name = 'session1';
      else:
          $session_name = 'session2';
      endif;
      session_start( $session_name );
      

      【讨论】:

      猜你喜欢
      • 2014-09-22
      • 2016-12-26
      • 2012-11-17
      • 2013-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      相关资源
      最近更新 更多