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