难以将用户从网站注销


Difficulty logging user out from website

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

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

检查浏览器数据表明,会话cookie在发出session_destroy()时无法删除,我无法通过编程方式将其删除。

我试图弄清楚为什么打开第二个网站页面(使用相同的会话参数)似乎会锁定会话,这样就不会从任何一个页面上破坏它。php手册中没有任何地方提出任何此类行为。

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

一段时间以来,我一直在努力解决这个问题。有什么想法吗?

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

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

现在关于你的问题,在没有看到代码的情况下很难说发生了什么,但这里有几个想法:

会话变量用随机数据单独重写,然后会话被破坏。

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

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

就像我说的,cookie不会自动删除;它更有可能没有固定下来。

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

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

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

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

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

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

谢谢。