强制用户注销会话 PHP

Posted

技术标签:

【中文标题】强制用户注销会话 PHP【英文标题】:Force user to logout session PHP 【发布时间】:2012-05-11 13:28:58 【问题描述】:

我似乎找不到这个问题的直接答案。有没有一种方法可以强制登录的用户注销?我的登录系统本质上只是依赖于一个包含用户唯一 ID(存储在 mysql 数据库中)的会话。所以本质上只是......

if (isset($_SESSION['user_id'])) 
echo "You're logged in!";
 else 
echo "You need to login!";

但是假设我想禁止这个用户,我可以在我的数据库中将他们的状态更改为禁止但在用户注销并尝试重新登录之前这不会做任何事情......那么,我该怎么做强制此用户注销?最好不要在每次查看页面时检查他们的状态是否已切换为“禁止”,因为这似乎对我的服务器造成了不必要的压力。任何帮助表示赞赏,谢谢。

【问题讨论】:

为什么不检查用户在登录过程中是否被禁止..? 我会在登录过程中进行检查,但如果他们不注销,尽管被禁止,他们仍可以继续使用该网站......我显然禁止他们是有原因的,我不想等他们好心退出。 Ian,你找到解决办法了吗? 【参考方案1】:

您需要在每次加载页面时进行检查,或者可能在设定的时间间隔内查看 Ajax 调用以从数据库中检查其状态。

然后您可以使用session_destroy(); 结束他们的会话。这将破坏他们的整个会话。

否则您可以使用unset($_SESSION['user_id']); 取消设置单个会话变量

【讨论】:

嗯,ajax 是一个有趣的想法,但熟练的用户可能会阻止调用。【参考方案2】:

最好不要在他们每次查看页面时检查他们的状态是否已切换为“禁止”,因为这似乎对我的服务器造成了不必要的压力。

在每次页面加载时从数据库中加载用户,而不是在会话中存储用户的副本,这是一个非常合理的解决方案。它还可以防止用户与数据库中的副本不同步(例如,您可以更改用户的属性或权限,而不必注销并重新登录)。

【讨论】:

+1。 “似乎对我的服务器造成了不必要的压力。” = 过早优化。【参考方案3】:

试着把它放在每一页上......

if (isset($_SESSION['user_id'])) 

    $sql = "SELECT from tbl where status='banned' and user_id=$_SESSION['user_id'] ";
    $query = mysql_query($sql);

    if(!empty(mysql_num_rows($query))) // found the banned user
       //redirect to logout or
       //session_destroy();
    

 else 
echo "You need to login!";

如果用户仍然登录...检查他/她的状态是否被禁止...如果被禁止...然后注销

【讨论】:

【参考方案4】:

您可以取消设置。

unset($_SESSION['user_id'])

【讨论】:

我想你误读了我的问题,我知道如何取消会话我不知道如何强制用户取消他们的会话,而不是每次都引用数据库。 我猜您想知道是否可以取消设置任意会话。答案是不。为他们提供页面的 php 脚本需要查询他们是否被禁止。无论如何,您应该在每次页面呈现时查询数据库以获取他们的基本用户信息,以防他们以某种方式更改它,所以只需检查他们是否被禁止并取消设置。 嗯,所以我应该在每次页面呈现时重置会话变量?如果他们更改了所需的会话变量(比如他们更改了存储在会话变量中的用户名),我会重置所需的会话变量,是否有特定的安全(或其他)原因我应该在每次页面加载时检查我不知道吗? 是的——这是唯一的方法。在 PHP 中,您不能说“取消设置此人的会话”,除非该页面正在提供给该人,并且因为禁止是在发送给您的页面中完成的,所以您只能将其放入数据库中并且等待他们从中读取。其他方式根本不可能。 好的,为了确定,我将在几个小时内不回答这个问题,但如果没有任何问题,我会选择你作为最佳答案。感谢您的帮助。【参考方案5】:

您可以使用Custom Session Handlers 这样您就可以完全控制会话数据在服务器上的存储位置和方式。

因此,您可以将特定用户的会话数据存储在名为<user_id>.session 的文件中。然后,要注销用户,只需删除该文件即可。

【讨论】:

嗯,知道这当然很好。不幸的是,我的 localhost 程序 (MAMP) 还没有启动对 PHP 5.4 的支持,所以我想我会继续研究这个解决方案,直到发生这种情况。谢谢。 此外,此解决方案通过在会话生命周期的每个周期执行 PHP 来减慢每个页面的速度,这通常由预编译代码处理。 @Ian:这甚至适用于 PHP4(参见:session_set_save_handler),只有新的 SessionHandlerInterface 需要 PHP >=5.4.0,这只是做同样事情的另一种方式。【参考方案6】:

间隔内的 Ajax 调用会给服务器带来额外的负载。如果您希望实时响应您的操作(例如,当您从系统后端禁止用户时,用户将立即退出),那么您应该查看类似 Server Push 的内容。

这个想法是在用户浏览您的网站时保持从服务器到浏览器的隧道打开,以便您也可以从服务器端与他们进行通信。如果您希望他们被禁止,请在您的页面中推送注销请求和进程(即通过取消会话强制注销)。

【讨论】:

【参考方案7】:

这对我有用,我使用的是 pHP 5.4 包括'connect.php';

  session_start();
  if(session_destroy())
  
     header("Location: login.php");
  

【讨论】:

【参考方案8】:

您可以使用session_save_path() 找到PHP 保存会话文件的路径,然后使用unlink() 删除它们。

一旦您删除存储在服务器中的会话文件,客户端PHPSESSID cookie 将不再有效进行身份验证,用户将自动退出您的应用程序。

在使用这种方法时请务必小心,如果有问题的路径是全局 /tmp 目录!除了 PHP 之外,肯定还有其他进程在那里存储临时数据。如果 PHP 为会话数据预留了自己的目录,那么它应该是相当安全的。

【讨论】:

【参考方案9】:

在我看来,基于安全性,有几种方法可以做到最好: 注意:这真的很粗糙......我知道语法是错误的,它只是为了让你得到一个想法。

$con = mysql_connect("localhost","sampleuser","samplepass");
if (!$con)

$error = "Could not connect to server";

mysql_select_db("sampledb", $con);
$result = mysql_query("SELECT * FROM `sampletable` WHERE `username`='".$_SESSION['user_id']."'");
$userdeets = mysql_fetch_array($result);
if($_SESSION['sessionvalue'] != $userdeets['sessionvalue'])

session_destroy();
Header('Location: logout.php');

else

$result2 = mysql_query("UPDATE `sessionvalue` WHERE `username`='".$_SESSION['user_id']."' SET `sessionvalue` = RANDOMVALUE''");
 $sesval = mysql_fetch_array($result2);
$_SESSION['sessionvalue'] = $seshval

现在我知道那不是代码,但本质上你需要做的是确保安全并拥有这种能力:

每次页面加载都会检查 Session 值是否与 DB 中的值匹配。 每次加载页面时,都会根据随机生成的 DB 值设置新的会话值。您还需要将用户名存储在会话中。 如果会话 ID 不匹配,则销毁会话并重定向它们。 如果匹配,则创建新的会话 ID。

如果您想禁止某个用户,您可以将他们在数据库中的 sessionvalue 设置为“BANNED”之类的值。此值也不允许他们登录。通过这种方式,您可以通过简单的 Web 表单控制用户,还可以非常轻松地生成禁止用户列表等。我希望我有更多时间来解释它,希望对您有所帮助。

【讨论】:

以上是关于强制用户注销会话 PHP的主要内容,如果未能解决你的问题,请参考以下文章

如果不活动10分钟,我如何使用php上的会话注销用户[重复]

Rails设计gem:强制注销浏览器选项卡关闭

如何使用php制作涉及会话cookie的注销页面?

当用户注销 php 中打开的选项卡之一时,自动注销所有打开的选项卡

如何注销单个帐户?

当用户关闭浏览器而不单击注销时销毁或取消设置会话[重复]