在同一个域中有两个不同的会话

时间:2009-08-28 18:07:42

标签: php

我跑foo.com。我在foo.com上有两个不同的应用程序:一个是foo.com/bar,另一个是foo.com/example。我使用会话来跟踪用户登录时的信息,但如果用户从foo.com/bar转到foo.com/example,则foo.com/example会看到用户从foo.com/开始的会话吧并使用该信息。我的问题是,如何同时为每个目录进行两次不同的会话?

6 个答案:

答案 0 :(得分:43)

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

为每个应用程序使用不同的名称。你不应该混淆会话中的变量。

答案 1 :(得分:4)

我认为强调与目前提供的解决方案相关的潜在安全隐患非常重要。 我已经成为一名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/应用程序上进行身份验证,获取其TESTTWO会话标识符的值,并将其用作{{1}的值将请求发送到TESTONE应用程序时的会话标识符。除了解析对应的值之外,PHP的会话查找过程不识别会话标识符的名称。即会话标识符值&#34; agcy648dja6syd8f93&#34;无论用于引用它的名称如何,都将返回相同的会话对象。

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:2)

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

编辑:抱歉,这不能解答您的问题,但提供了另一种解决方案。

答案 4 :(得分:0)

另一种解决方案是通过预先挂起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中使用的变量名称。另一个是,如果您决定更改存储会话值的方式,您可以轻松地在一个地方更改所有内容。

答案 5 :(得分:0)

我意识到这是旧的,但认为它可能对某人有所帮助。此示例显示了我们如何为管理区域设置单独的会话。

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