У меня есть скрипт, который использует PHP SESSION
, Я управляю сессиями PHP, используя класс. В этом классе у меня есть метод, который возвращает количество секунд, оставшихся до истечения сеанса.
Кроме того, каждый раз, когда пользователь обновляет страницу или открывает новую страницу (новый запрос к серверу), счетчик времени простоя запускается заново. $_SESSION['MA_IDLE_TIMEOUT'] = time()+900;
То, что я хочу сделать, это отобразить диалоговое сообщение за 2 минуты до окончания сеанса PHP и проверить, находится ли пользователь на странице или нет. Если пользователь нажимает «Продолжить работу», сценарий jQuery отправит запрос PHP AJAX на возобновление сеанса. $_SESSION['MA_IDLE_TIMEOUT'] = time()+900;
, Если пользователь ничего не щелкнул или нажал «Выйти», сеанс завершается, и пользователь перенаправляется на страницу входа.
Я нашел хороший плагин, который в некоторой степени делает работу JQuery-ожидание тайм-аут
Проблема с этим плагином заключается в том, что он проверяет, не используется ли пользователь с помощью JavaScript (если используется клавиатура / мышь). Вот сценарий, где этот сценарий мне не помогает: допустим, у моих сессий PHP есть ограничение в 15 минут / 900 секунд. Пользователь читает супер длинную статью на той же странице. Он / она будет прокручивать, они на самом деле не бездействуют «с точки зрения JavaScript», но с точки зрения PHP использование бездействует. Затем через 20 минут пользователь обновит страницу, после чего пользователь выйдет из системы, поскольку он / она не отправил новый запрос на сервер PHP более чем на 900 секунд.
Как я могу решить эту проблему? Есть ли лучший плагин, чтобы сделать трюк? если что-то пропустил в этом плагине, который решит мою проблему?
Спасибо
Если пользователь не выполняет запросы, не двигает мышь или клавиатуру, не касается устройства и т. Д., То с точки зрения приложения пользователь «бездействует», даже если его глазные яблоки не движутся.
Если пользователь выполняет прокрутку, вы можете использовать JavaScript для прослушивания событий прокрутки (через onscroll
, например), но это не будет на 100% надежно, потому что (1) зависит от javascript и (2) не работает, если вы просматриваете короткую статью или используете монитор высокого / большого формата (например, те, которые вы можете поворот на 90 градусов, например).
Возможно, вы могли бы справиться с этим по-другому: использовать файлы cookie, единый вход или аналогичные методы для предварительной аутентификации или автоматической аутентификации запросов, чтобы сеанс пользователя мог благополучно прерваться и перезапуститься без необходимости входа пользователя вручную.
Другой способ справиться с этим — поддерживать процесс ping, который регулярно проверяет связь с сервером (через setInterval()
например, чтобы поддерживать сеанс в рабочем состоянии, и использует отдельный тайм-аут (может быть, что-то вроде «таймаута аутентификации», который использует ASP.NET), чтобы отслеживать, когда «неактивный» пользователь должен выйти из системы. Затем пользовательские действия, такие как прокрутка, запрос страниц, фокусировка на полях, перемещение мыши и т. Д., Могут выполнить «сброс пинга», который сбрасывает счетчик простоя на 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);
Я использую временной куки для выхода из системы неактивного пользователя, как это:
`$time = time();
// 5 minutes since last request
if(!empty($_COOKIE['_time'] && $time - $_COOKIE['_time'] >= 300)
{
// log user out
}
setcookie('_time', $time, '/');`
Надеюсь это поможет.