Php 很难将用户从网站注销

Php 很难将用户从网站注销,php,session,browser,login,destroy,Php,Session,Browser,Login,Destroy,写一个小CMS。用户身份验证是由php在命名会话中设置的会话变量进行的。当调用注销时,ajax例程将加载一个单独的php脚本来完成这项工作。这个单独的脚本使用相同的会话参数。会话变量使用随机数据逐个重写,然后销毁会话。这很有效。注销后检查浏览器cookie列表显示会话cookie已被删除。到目前为止,一切正常 如果用户在登录时导航到同一站点的另一页,或者在新的浏览器选项卡中打开第二页,则会出现问题。完成任一操作后,注销例程将无法销毁或取消会话。更糟糕的是,即使密码会话变量在注销时随机化,重新加载

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

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

检查浏览器数据表明,在发出会话_destroy()时,会话cookie未能删除,并且我无法以编程方式将其删除

我试图弄明白为什么打开第二个站点页面(使用相同的会话参数)似乎应该锁定会话,这样就不能从任何一个页面销毁会话。php手册中没有提出任何此类行为

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

这件事已经纠缠了一段时间了。有什么想法吗

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

session\u destroy()
不会取消会话cookie的设置(或者为此重置
$\u session
全局变量);它仅销毁服务器端会话数据存储(默认的基于文件的会话配置中的文件)。删除cookie(可以使用带有空值的
setcookie()
“手动”完成)不是销毁会话数据所必需的。当调用了
session\u destroy()
但cookie保持不变时,在后续请求中使用
session\u start()
将启动一个新的会话,该会话具有相同的ID(除非您也调用了
session\u regenerate\u ID()
),但具有否的会话数据

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

会话变量使用随机数据单独重写, 然后会话被销毁

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

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

就像我说的,饼干不会被自动移除;更可能的是它没有被设置好

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

这表明
会话\u destroy()
实际上没有销毁任何东西。这导致我怀疑在您的注销脚本中,您在尝试销毁会话之前没有初始化会话(使用
session\u start()
)。这将导致一个PHP警告,您可能看不到该警告,因为您已抑制了警告,或者因为脚本是通过AJAX调用的

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


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

MarcB有答案-必须在销毁会话之前发出session\u write\u close()

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


谢谢

不要把密码放在会话变量中…永远…像以前一样…这很糟糕。如果你读了,你会看到它清楚地表明它没有删除会话cookie。您必须使用setcookie()调用来取消设置它。真正需要“杀死”会话的是
$\u session=array();会话写入关闭()
。这将强制将一个空白会话提交到磁盘,而您的用户实际上被遗忘/注销。这里涉及的问题很多,需要大量的文字才能涵盖所有这些问题。基本上,该机制可以完美地用于单个页面,因此我看不出它无法设置或删除会话数据。当第二个页面打开时(或之后),会话数据就呈现出吸血鬼般的存在。在此之后,使用js或php命令删除会话cookie的尝试也会失败。顺便说一句,密码不是以明文形式存储的。它是一个盐哈希。