我在使用 PHP 做一些非常基本的会话安全类型的事情时遇到了困难:
- 当从非认证的上下文切换到认证的上下文时,应该生成一个新的会话 ID
- 从经过身份验证的上下文切换到未经过身份验证的上下文时,应生成新的会话 ID
我想做的不仅是在切换上下文时重新生成会话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
-但即使我没有,session_regenerate_id(TRUE)
也应该使旧的会话 ID 无效-因此,即使浏览器由于某种原因没有获得新的会话 ID,它也不会看到会话中的任何信息,因为旧会话已失效。
有没有其他人遇到过这类问题?有没有解决这些问题的好方法?