纯粹的服务器端PHP。每次用户提交表单时,我都会更新数据库中的“上次活动”时间。
我想定期检查并强制注销非活动用户以释放许可证。
我该怎么做?我是否还应该将会话ID存储在数据库中,然后销毁会话?这将释放另一个用户的许可证,当第一个最终提交另一个表单时,如果会话仍然存在,我可以在每个表单操作文件的顶部检查,并在必要时将用户重定向到登录页面。
那会有用吗?这是'最好'的方式吗?任何示例代码?
更新:我正在轮询,因为我需要知道用户何时超时才能更新数据库。
答案 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.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)
所有这些解决方案都很有趣并且运作良好。
但是:如果您在基于帧的内容窗口中会怎样?
然后有两个选择:
在注销或调用注销脚本之前,必须到达页面的基于框架的顶部(可以使用JavaScript命令“取消”框架中当前位置的深度来完成)
或者,可以调用帧破坏者或帧杀手脚本来重置到顶部位置,例如
<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";
}
});
最好的问候。