1

我有一个使用 PHP 的脚本SESSION。我使用一个类来管理 PHP 会话。在这个类中,我有一个方法返回会话到期前剩余的秒数。

此外,在用户刷新页面或打开新页面(对服务器的新请求)时,空闲时间计数器重新开始$_SESSION['MA_IDLE_TIMEOUT'] = time()+900;

我要做的是在 PHP 会话到期前 2 分钟显示一条对话框消息,并检查用户是否仍在页面上。如果用户单击“继续工作”,则 jQuery 脚本将发送 PHP AJAX 请求以更新会话 $_SESSION['MA_IDLE_TIMEOUT'] = time()+900;。如果用户没有单击任何内容或单击“注销”,则会话结束并将用户重定向到登录页面。

我确实找到了一个不错的插件,它可以在某种程度上完成 Job jquery-idle-timeout

这个插件的问题是它检查用户是否使用 JavaScript(如果键盘/鼠标)正在使用空闲。这是这个脚本对我没有帮助的场景:假设我的 PHP 会话有 15 分钟/900 秒的限制。用户正在同一页面上阅读超长文章。他/她将滚动,“从 JavaScript 的角度来看”它们并不是真正空闲的,但从 PHP 的角度来看,使用是空闲的。然后在 20 分钟后用户刷新页面,然后用户将被注销,因为他/她没有向 PHP 服务器发送新请求超过 900 秒的限制。

我怎么解决这个问题?有没有更好的插件来解决这个问题?如果我在这个插件中遗漏了什么可以解决我的问题?

谢谢

4

2 回答 2

2

如果用户没有发出请求,也没有移动鼠标或键盘或触摸设备等,那么从应用程序的角度来看,即使他们的眼球没有,用户也是“空闲的”。

如果用户正在滚动,您可以使用 javascript 来监听滚动事件(onscroll例如,通过 ),但这不是 100% 可靠的,因为 (1) 依赖于 javascript,并且 (2) 如果您正在查看简短的文章或使用高/大幅面显示器(例如可以旋转 90 度的显示器)。

也许您可以用不同的方式处理这个问题:使用 cookie、单点登录或类似技术来预先验证或自动验证请求,以便用户的会话可以安全地终止并重新启动,而无需用户手动登录。

您可以处理此问题的另一种方法是维护一个“ping”进程,该进程定期 ping 服务器(setInterval()例如,通过 )以保持会话处于活动状态,并使用单独的超时(可能类似于 ASP.NET 的“身份验证超时”)使用)来跟踪何时应该注销“空闲”用户。然后用户操作,如滚动、请求页面、聚焦字段、移动鼠标​​等,可以执行“ping 重置”,将空闲计数器重置为 0。

示例/概念 - 作为练习留给读者完善它:

var idleTime = 0; // how long user is idle
var idleTimeout = 1000 * 60 * 20; // logout if user is idle for 20 mins
var pingFrequency = 1000 * 60; // ping every 60 seconds
var warningTime = 1000 * 60 * 2; // warning at 2 mins left
var warningVisible = false; // whether user has been warned
setInterval(SendPing, pingFrequency);
setInterval(IdleCounter, 1000); // fire every second
function IdleCounter() {
    idleTime += 1000; // update idleTime (possible logic flaws here; untested example)
    if (console) console.log("Idle time incremented. Now = " + idleTime.toString());
}

function SendPing() {
    if (idleTime < idleTimeout) {
        // keep pinging
        var pingUrl = "tools/keepSessionAlive.php?idleTime=" + idleTime;
        $.ajax({
            url: pingUrl,
            success: function () {
                if (console) console.log("Ping response received");
            },
            error: function () {
                if (console) console.log("Ping response error");
            }
        });

        // if 2 mins left, could show a warning with "Keep me on" button
        if ((idleTime <= (idleTimeout - (idleTimeout - warningTime))) && !warningVisible) {
            ShowTimeoutWarning();
        }
    } else {
        // user idle too long, kick 'em out!
        if (console) console.log("Idle timeout reached, logging user out..");
        alert("You will be logged off now dude");
        window.location.href = "logoff.aspx"; // redirect to "bye" page that kills session
    }
}

function ShowTimeoutWarning() {
    // use jQuery UI dialog or something fun for the warning
    // when user clicks OK set warningVisible = false, and idleTime = 0
    if (console) console.log("User was warned of impending logoff");
}

function ResetIdleTime() {
    // user did something; reset idle counter
    idleTime = 0;
    if (console) console.log("Idle time reset to 0");
}
$(document) // various events that can reset idle time
.on("mousemove", ResetIdleTime)
    .on("click", ResetIdleTime)
    .on("keydown", ResetIdleTime)
    .children("body")
    .on("scroll", ResetIdleTime);
于 2014-10-23T21:34:52.903 回答
1

我使用时间 cookie 来注销非活动用户,如下所示:

`$time = time();
// 5 minutes since last request
if(!empty($_COOKIE['_time'] && $time - $_COOKIE['_time'] >= 300) 
{
    // log user out
}
setcookie('_time', $time, '/');`

希望这可以帮助。

于 2014-10-23T22:18:35.403 回答