0

编写一个小型 CMS。用户身份验证是通过在命名会话中使用 php 设置的会话变量进行的。调用注销时,ajax 例程会加载一个单独的 php 脚本来完成这项工作。这个单独的脚本使用相同的会话参数。会话变量被随机数据单独覆盖,然后会话被销毁。这行得通。注销后检查浏览器 cookie 列表显示会话 cookie 已被删除。到目前为止,一切正常。

如果用户在登录时导航到同一站点的另一个页面,或者在新的浏览器选项卡中打开第二个页面,则会出现问题。一旦完成,注销例程就不能破坏或取消设置会话。更糟糕的是,即使密码会话变量在注销时是随机的,重新加载页面也会将其恢复为之前的值,从而有效地让用户重新登录。

检查浏览器数据显示会话 cookie 在发出 session_destroy() 时未能删除,我无法以编程方式将其删除。

我试图弄清楚为什么打开第二个站点页面(使用相同的会话参数)似乎应该锁定会话,因此它不能从任何一个页面被破坏。php手册没有任何地方建议任何此类行为。

浏览器缓存被认为是可能的罪魁祸首,但似乎不太可能。

一直在为此苦苦挣扎。有任何想法吗?

测试在 Firefox 中完成,版本 6 到最新。

4

2 回答 2

0

MarcB 有答案 - session_write_close() 必须在销毁会话之前发出。

在 ajax 注销例程中,从任何页面注销都会杀死用户对所有打开页面的编辑权限,这是应该的。

谢谢。

于 2013-08-21T08:50:07.810 回答
0

session_destroy()不会取消设置会话 cookie(或$_SESSION为此重置全局变量);它只会破坏服务器端会话数据存储(默认的基于文件的会话配置中的文件)。删除 cookie(可以使用setcookie()空值“手动”完成)对于销毁会话数据不是必需的。Whensession_destroy()被调用但 cookie 保持不变,session_start()在后续请求中使用将启动一个具有相同 ID(除非您也调用)但没有会话数据的新会话。session_regenerate_id()

现在关于您的问题,如果没有看到代码,真的很难说出发生了什么,但这里有一些想法:

会话变量被随机数据单独覆盖,然后会话被销毁。

在调用之前将会话数据设置为任何值是没有意义的,session_destroy()因为这些新值永远不会进入会话数据存储。

注销后检查浏览器 cookie 列表显示会话 cookie 已被删除。

就像我说的,cookie 不会被自动删除。它更有可能没有设置。

更糟糕的是,即使密码会话变量在注销时是随机的,重新加载页面也会将其恢复为之前的值

这表明session_destroy()它实际上并没有破坏任何东西。session_start()这使我怀疑在您的注销脚本中,您在尝试销毁会话之前没有初始化会话(使用)。这应该会导致您可能看不到 PHP 警告,因为您已禁止警告,或者因为脚本是通过 AJAX 调用的。

另一种可能性较小的可能性是您的注销脚本确实启动然后销毁会话,但完全不同。使用 Firebug 或类似工具查看是否(以及什么)会话 cookie 与您的 AJAX 请求一起发送。

最后,正如有人已经提到的那样:如果您需要将密码存储在会话变量中,您可能需要重新考虑您的整个身份验证机制,但这是一个完全不同的主题。

于 2013-08-21T00:36:30.770 回答