简体   繁体   English

难以从网站注销用户

[英]Difficulty logging user out from website

Writing a small CMS. 编写一个小型CMS。 User authentication is by session variables set with php, in a named session. 用户身份验证是通过在命名会话中用php设置的会话变量进行的。 When logout is called, an ajax routine loads a separate php script which does the work. 调用注销时,Ajax例程会加载一个单独的PHP脚本来完成工作。 This separate script uses the same session parameters. 此单独的脚本使用相同的会话参数。 The session variables are over-written individually with random data, and the session is then destroyed. 使用随机数据分别覆盖会话变量,然后销毁会话。 This works. 这可行。 Examining the browser cookie-list after logout shows that the session cookie has been removed. 注销后检查浏览器cookie列表显示会话cookie已被删除。 So far, all OK. 到目前为止,一切正常。

Problem arises if the user either navigates away to another page of the same site whilst logged on, or opens a second page in a new browser tab. 如果用户在登录时导航到同一站点的另一个页面,或者在新的浏览器选项卡中打开第二个页面,则会出现问题。 Once either has been done, the logout routine cannot destroy or unset the session. 一旦完成,注销例程就无法破坏或取消会话设置。 Worse, even if the password session variable was randomized at logout, reloading the page reinstates it to its previous value, effectively logging the user back on. 更糟糕的是,即使注销时密码会话变量是随机的,重新加载页面也会将其恢复为之前的值,从而有效地将用户重新登录。

Examining the browser data shows that the session cookie has failed to delete on session_destroy() being issued, and nothing I can do programmatically will delete it. 检查浏览器数据后,发现会话cookie在发出session_destroy()时未能删除,并且我无法以编程方式执行的任何操作将其删除。

I'm trying to figure out why opening a second site page (which uses the same session parameters) should seemingly lock the session so it cannot be destroyed from either page. 我试图弄清楚为什么打开第二个站点页面(使用相同的会话参数)似乎应该锁定会话,以便不能从任何一个页面中删除它。 Nowhere does the php manual suggest any such behaviour. php手册在任何地方都没有建议任何此类行为。

Browser cacheing has been suggested as a possible culprit, but seems unlikely. 已建议将浏览器缓存作为罪魁祸首,但似乎不太可能。

Been wrestling with this for some time. 摔跤了一段时间。 Any ideas? 有任何想法吗?

Testing done in Firefox, versions 6 to latest. 测试已在Firefox版本6到最新版本中完成。

session_destroy() doesn't unset the session cookie (or reset the $_SESSION global variable for that matter); session_destroy()不会取消设置会话cookie(或为此重置$_SESSION全局变量); it only destroys the server-side session data storage (a file in the default, file-based sessions configuration). 它只会破坏服务器端会话数据存储(默认的基于文件的会话配置中的文件)。 Removing the cookie (which can be done "manually" using setcookie() with an empty value) is not necessary to destroy the session data. 删除cookie(可以使用具有空值的setcookie() “手动”完成)来删除会话数据不是必需的。 When session_destroy() is called but the cookie is left intact, using session_start() on a subsequent request will start a new session with the same ID (unless you also call session_regenerate_id() ) but with no session data. session_destroy()被调用但cookie保持不变时,在后续请求上使用session_start()将启动一个具有相同ID会话(除非您也调用session_regenerate_id() )但没有会话数据。

Now regarding your problem, it's really hard to say what's going on without seeing the code, but here's a couple of thoughts: 现在,关于您的问题,很难在不看代码的情况下说出正在发生的事情,但是这里有一些想法:

The session variables are over-written individually with random data, and the session is then destroyed. 使用随机数据分别覆盖会话变量,然后销毁会话。

There's no point in setting the session data to anything prior to calling session_destroy() since these new values will never make it to the session data storage. 在调用session_destroy()之前,没有必要将会话数据设置为任何值,因为这些新值将永远不会将其存储到会话数据存储中。

Examining the browser cookie-list after logout shows that the session cookie has been removed. 注销后检查浏览器cookie列表显示会话cookie已被删除。

Like I said, the cookie doesn't get removed automatically; 就像我说的那样,cookie不会自动删除。 it's more likely it din't get set. 它更有可能没有被设置。

Worse, even if the password session variable was randomized at logout, reloading the page reinstates it to its previous value 更糟糕的是,即使注销时密码会话变量是随机的,重新加载页面也会将其恢复为之前的值

This would suggest the session_destroy() doesn't actually destroy anything. 这表明session_destroy()实际上并没有破坏任何东西。 Which leads me to a suspition that in your logout script you don't initialize the session (with session_start() ) before trying to destroy it. 令我感到怀疑的是,在注销脚本中,您没有在试图销毁会话之前初始化会话(使用session_start() )。 This should result in a PHP warning which you might not see because you have warning suppressed, or because the script is called through AJAX. 这将导致PHP警告,您可能看不到该警告,因为您已禁止警告,或者因为脚本是通过AJAX调用的。

Another, altough less likely possibility is that your logout script does start and then destroy a session, but a completely different one. 另一种可能性较小的可能性是,注销脚本确实会启动然后破坏会话,但这是一个完全不同的会话。 Use Firebug or a similar tool to see if (and what) session cookie is sent with your AJAX request. 使用Firebug或类似工具查看会话Cookie是否随AJAX请求一起发送。

And finally, as someone has already mentioned: you might want to rethink your entire authentication mechanism if you need to store passwords in session variables, but that's a completely different topic. 最后,就像有人已经提到的那样:如果需要将密码存储在会话变量中,则可能需要重新考虑整个身份验证机制,但这是一个完全不同的主题。

MarcB has the answer - session_write_close() must be issued before destroying the session. MarcB有答案-必须在销毁会话之前发出session_write_close()。

With this in the ajax logout routine, logging out from any page kills the user's editing rights on all open pages, as it should. 在ajax注销例程中使用此选项,从任何页面注销都将按原样取消用户在所有打开的页面上的编辑权限。

Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM