我需要以这种方式限制只能登录一次,以便用户不能同时使用一个帐户多次登录。用户也可以登录到不同的服务器,所以我不能使用 session_destroy,我需要“手动”删除 session 。
当使用带有文件存储的 session 时,它工作正常,我删除文件,登录新用户都工作得很好。但是,当我将 session 与内存缓存一起使用时,我可以从内存缓存中删除 session ,但同一请求中的进一步登录会丢失。
我就是这样做的:
session_regenerate_id();
$session_id = session_id();
$m = new Memcache();
$m->connect('XXX.XXX.XXX.XXX', 11211);
$ans = $m->delete(SESSION_ID_OF_ALREADY_LOGGED_USER);
$query = "UPDATE activeLogins SET activeSession = '{$session_id}' WHERE userEmail = $safeEmail LIMIT 1";
$dbh->exec($query);
//Login new user...
知道可能出了什么问题吗?
最佳答案
根据数据库中存储的内容检查 session ID
据我了解,您希望将一个用户限制在一台客户端计算机上。该机器应该是最后登录的机器。我认为您应该能够通过对每个页面加载进行简单检查来实现此目的。
从您的问题中我可以看到您的数据库有一个名为 activeLogins
的表,其中至少包含以下字段:activeSession
和 userEmail
。
据此,我假设电子邮件地址是唯一标识用户的。因此,在新登录后,您将拥有 $session_id
、$safeEmail
以及 activeLogins
表中相应的更新行。
现在假设用户没有从旧机器上注销?下一个页面加载时会发生什么(在更新 activeLogins
表之前)?是的,activeSession
将与该服务器上的 $session_id
不同。请记住,新的登录名改变了它。
因此,您需要做的就是检查 $session_id
是否与 activeLogins
表中的 activeSession
匹配。
我还建议仅在新登录后更新 activeLogins
表,而不是在每个页面加载时更新。虽然从你的问题中并不清楚你是否这样做。
我不确定这是否能真正回答您的问题。这似乎是一个简单的答案。不过你的问题问的不是很清楚。您真的在每次页面加载时使用您向我们展示的代码吗?!
为了回应您的所有答案,我一直在寻找将通知从服务器推送到客户端计算机的最佳方法。您自己提到的一种方法是 ajax 轮询,但我认为这是一种不好的做法,不应使用。
有 Ratchet (http://socketo.me),它为您提供持续的连接。当检测到另一个登录时,您可以简单地删除连接并在旧客户端中使用react。
还有一个更高级别的接口(interface),用于将事件从服务器发送到客户端:
https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events
但是 IE 不支持该功能,因此一般不可用。
您还可以查看http://pusher.com
所有这些建议的要点是,您可以有效地向客户端发出信号,表明它应该删除对您所服务的网站的访问权限,而无需不断轮询。
关于php - 从远程服务器删除内存缓存 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26360415/