我在使用PHP做一些非常基本的会话安全类型时遇到了困难:
我想做的不仅是在切换上下文时重新生成会话ID,而且在切换这些上下文时还会立即将某些内容放入会话中(例如FLASH)。这三页应该有希望澄清我的期望:
<?php
/* page1.php */
session_start();
# Just putting something in the session which I expect to
# not show up later
$_SESSION['INFO1'] = 'INFO1';
?>
<html>
<a href="page2.php">Page 2</a>
<?php print_r($_SESSION) ?>
</html>
因此,当显示此页面时,我希望看到INFO1
显示。我也期待当我回到这里时,不要看到INFO2
出现。如果我还没有会话ID,我希望得到一个(我愿意)。
<?php
# page2.php
session_destroy();
session_regenerate_id(TRUE);
$_SESSION['INFO2'] = 'From page 2';
session_write_close();
header('Location: page3.php');
exit;
?>
这最类似于注销功能 - 我们通过将TRUE
传递给session_regenerate_id
来使现有会话无效。此外,我在(可能)新会话中添加了一些内容 - 可能就像FLASH一样 - 说“您已成功注销。
#page3.php
<html>
<body>
<?php session_start(); ?>
<?php print_r($_SESSION); ?>
</body>
</html>
在这个页面上,我期待发生两件事:
page2.php
的重定向应该向我发送一个新的会话ID cookie(它没有)print_r
打印来自INFO2
的信息,不来自INFO1
。它没有来自INFO1
的信息,但不包含来自INFO2
的信息。我与session_regenerate_id
和重定向的结果非常非常不一致。手动发送Set-Cookie
标题看起来像是一个kludge - 但即使我没有,session_regenerate_id(TRUE)
无论如何都应该使旧的会话ID无效 - 所以即使浏览器由于某种原因没有得到新会话ID,它不会在会话中看到任何信息,因为旧会话已失效。
还有其他人有过这类问题的经验吗?有没有办法解决这些问题?
答案 0 :(得分:4)
根据session_regenerate_id
的{{3}},听起来总是会保留会话的内容。你传递了一个TRUE
参数,但只删除磁盘上的实际会话文件;存储在其中的值保存在$_SESSION
中,然后写入新会话。
所以也许可以手动擦除它:
$_SESSION = array();
不知道为什么你没有看到新的cookie。你在哪里检查,你看到了什么?
编辑:正如OP在下面的评论中所揭示的那样,问题似乎是page2从未调用session_start
来加载第一个会话。产生以下内容:
<?php
session_start(); # Load the old session
session_destroy(); # Nuke it
session_unset(); # Delete its contents
session_start(); # Create a new session
session_regenerate_id(TRUE); # Ensure it has a new id
$_SESSION['FLASH'] = "You've been logged out";
session_write_close(); # Convince it to write
header('Location: index.php');
?>
我不知道这是否是最小的。弄清楚它有多少可以删除,留给读者练习。