如何由于不活动而将用户注销

时间:2011-04-30 02:41:34

标签: php session session-timeout

纯粹的服务器端PHP。每次用户提交表单时,我都会更新数据库中的“上次活动”时间。

我想定期检查并强制注销非活动用户以释放许可证。

我该怎么做?我是否还应该将会话ID存储在数据库中,然后销毁会话?这将释放另一个用户的许可证,当第一个最终提交另一个表单时,如果会话仍然存在,我可以在每个表单操作文件的顶部检查,并在必要时将用户重定向到登录页面。

那会有用吗?这是'最好'的方式吗?任何示例代码?


更新:我正在轮询,因为我需要知道用户何时超时才能更新数据库。

7 个答案:

答案 0 :(得分:4)

每次登录时,您都需要跟踪会话开始时间,可以这样做:

$_SESSION['SessionStartTime'] = time();

每个用户请求执行任何操作,您都需要运行此脚本来监视不活动状态。

<?php
session_start();
$TimeOutMinutes = 15; // This is your TimeOut period in minutes
$LogOff_URL = "login.php"; // If timed out, it will be redirected to this page

$TimeOutSeconds = $TimeOutMinutes * 60; // TimeOut in Seconds
if (isset($_SESSION['SessionStartTime'])) {
    $InactiveTime = time() - $_SESSION['SessionStartTime'];
    if ($InActiveTime >= $TimeOutSeconds) {
        session_destroy();
        header("Location: $LogOff_URL");
    }
}
$_SESSION['SessionStartTime'] = time();
?> 

答案 1 :(得分:3)

您可以使用JavaScript完全执行此操作。启动倒计时器。然后等待活动并重置此计时器。如果没有活动且计时器熄灭,您可以调用注销序列。

例如:

<body onmousemove="reset_interval()" onclick="reset_interval()" onkeypress="reset_interval()" onscroll="reset_interval()">


<script type="text/javascript">
function set_interval(){
  //the interval 'timer' is set as soon as the page loads
  timer=setInterval("auto_logout()",10000);
  // the figure '10000' above indicates how many milliseconds the timer be set to.
  //Eg: to set it to 5 mins, calculate 5min= 5x60=300 sec = 300,000 millisec.So set it to 3000000
}

function reset_interval(){
  //resets the timer. The timer is reset on each of the below events:
  // 1. mousemove   2. mouseclick   3. key press 4. scroliing
  //first step: clear the existing timer
  clearInterval(timer);
  //second step: implement the timer again
  timer=setInterval("auto_logout()",10000);
  ..completed the reset of the timer
}

function auto_logout(){
  //this function will redirect the user to the logout script
  window.location="your_logout_script_location_here";
}
</script>

希望有所帮助。

PS:参考来自:http://www.w3hobbyist.com/web-designing/auto-logout-after-some-time-of-inactivity-with-javascript/

答案 2 :(得分:3)

  

我想定期检查一下   强制注销非活动用户释放   许可证

我认为你的意思是..当一个会话已经(应该)过期时,你需要“做点什么”来释放许可证,并且你希望它在服务器端受控制。

session.gc_maxlifetime在这里受到伤害,因为PHP在销毁会话时不会发送通知。

您需要一个cron作业来扫描PHP会话文件夹,查找其atime超过您的超时并释放其许可证的会话(并删除会话)。这样一个脚本的开头是

cd / path / to / sessions;找-cmin +24 | xargs rm

取自底部 http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime 您将用对您更有用的东西替换 xargs rm

答案 3 :(得分:2)

这个问题比表面看起来更困难。

您需要考虑三个不同级别的会话行为:

  • PHP
  • 数据库
  • 浏览器

<强> PHP

对于PHP,您需要将会话超时设置为您限制的任何内容。以下是php.net的一些示例代码:

<?php
session_cache_limiter('private');
/* set the cache expire to 30 minutes */
session_cache_expire(30);    
session_start();
?>

<强>数据库

听起来您需要跟踪活动的会话数,以便您可以强制执行许可。由于您使用的是PHP,因此您需要在数据库级别执行此操作。每个请求都可以为用户写入“最后请求时间”(UPDATE users SET last_access=NOW() WHERE user_id=?),然后您可以推测活动会话是最近30分钟内的会话。

您可以尝试再次在数据库中跟踪活动会话,而不是“上次访问时间”。我不确定如何在PHP中做得最好。我想你可以修补PHP的会话删除代码。我相信在会话到期时可以让它调用一个函数,但我还没有这样做。

<强>浏览器

只要您有服务器端超时,就可以使用Javascript轮询,但不是必需的。考虑用户关闭Javascript的情况,或者您有一些导致脚本停止运行的Javascript错误。

我们有一个非常Ajax的网站,所以Javascript很重要。当用户执行与打开页面上的面板无关的事情时,可能会发现超时。 I wrote up my recent experience here.

答案 4 :(得分:1)

所有这些解决方案都很有趣并且运作良好。

但是:如果您在基于帧的内容窗口中会怎样?

然后有两个选择:

  1. 在注销或调用注销脚本之前,必须到达页面的基于框架的顶部(可以使用JavaScript命令“取消”框架中当前位置的深度来完成)

  2. 或者,可以调用帧破坏者或帧杀手脚本来重置到顶部位置,例如

  3. <style> html{display : none ; } </style>
    <script>
    if( self == top ) {
    document.documentElement.style.display = 'block' ;
    } else {
    top.location = self.location ;
    }
    </script>

    (c.o.WikiPedia:http://en.wikipedia.org/wiki/Framekiller

    通过简单的互联网搜索“framebuster”或“framekiller”,可以从各种来源读取有关帧破坏者和帧杀手的更多信息。

答案 5 :(得分:1)

这是我的版本直接基于RKh的答案。

如果会话尚未超时,此版本将重新设置计时器。因此,您可以将整个块粘贴到session_start()下面,并且每次用户请求执行操作时都不必单独调用它。

/* Control Session Timeout */
if (!isset($_SESSION['LastActivity'])) {
$_SESSION['LastActivity'] = time();
}
//Set Timeout Window in Minutes
$TimeOutMinutes = 5;
//TimeOut in Seconds
$TimeOutSeconds = $TimeOutMinutes * 60; 

if (isset($_SESSION['LastActivity'])) {
    $InactiveTime = time() - $_SESSION['LastActivity'];
        //If Inactive Time more than timeout value log the user out
        if ($InactiveTime >= $TimeOutSeconds) {
            session_destroy();
            header("Location: $baseURL");
        }
        //If Inactive Time less than timeout reset the last activity to current time
        elseif ($InactiveTime < $TimeOutSeconds) {
            $_SESSION['LastActivity'] = time();
        }
    }

答案 6 :(得分:-1)

我使用jQuery获得了这个简单的解决方案。

var idleTime = 0;
var start = new Date();
var end;

// if mousemove, a keypressed or a mouse click events fired
$(document).on('mousemove keydown click', function() {
    end = new Date();
    idleTime = (end.getTime() - start.getTime()) /1000;
    // 30 seconds of idle time
    if ( idleTime > 30 ) {
        // logout/endsession code here 
        //window.location.href="logout.php";
    }
}); 

最好的问候。