Как выйти из системы из-за неактивности - PullRequest
4 голосов
/ 30 апреля 2011

Чистый серверный PHP.Каждый раз, когда пользователь отправляет форму, я обновляю время «последнего действия» в базе данных.

Я хочу сделать периодическую проверку и принудительно выйти из системы неактивных пользователей, чтобы освободить лицензии.

Как бы я это сделал?Должен ли я также сохранить идентификатор сеанса в базе данных, а затем уничтожить сеанс?Это освободит лицензию для другого пользователя, и когда первая наконец отправит другую форму, я могу проверить в верхней части каждого файла действия формы, существует ли сеанс, и перенаправить пользователя на страницу входа в систему, если необходимо.Будет ли это работать?это «лучший» способ?Любой пример кода?


Обновление: я опрашиваю, потому что мне нужно знать, когда истекло время ожидания пользователя для обновления базы данных.

Ответы [ 7 ]

4 голосов
/ 30 апреля 2011

При каждом входе в систему необходимо отслеживать время начала сеанса, что можно сделать следующим образом:

$_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();
?> 
3 голосов
/ 30 апреля 2011

Я хочу сделать периодическую проверку и вынудить неактивных пользователей выйти из системы лицензии

Полагаю, вы имели в виду ... Когда сеанс истек (должен был) истечь, вам нужно «сделать что-то», чтобы освободить лицензию, и вы хотите, чтобы она контролировалась на стороне сервера.

session.gc_maxlifetime причиняет боль здесь, потому что PHP не отправляет уведомление, когда уничтожает сеанс.

Вам нужно задание cron для сканирования папки сессий PHP на предмет сессий, время которых превысило ваше время ожидания, и освободить их лицензию (а также удалить сессию). Начало такого сценария

CD / путь / к / сессий; найти -cmin +24 | xargs rm

который был взят со дна http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime Вы замените xargs rm на что-то более полезное для вас.

3 голосов
/ 30 апреля 2011

Вы можете сделать это исключительно с помощью 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>

Надеюсь, что это поможет.http://www.w3hobbyist.com/web-designing/auto-logout-after-some-time-of-inactivity-with-javascript/

2 голосов
/ 30 апреля 2011

Эта проблема сложнее, чем кажется на первый взгляд.

Необходимо учитывать поведение сеанса на трех разных уровнях:

  • 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 важен.Тайм-аут может быть обнаружен, когда пользователь делает что-то столь же безобидное, как открытие панели на странице. Я описал свой недавний опыт здесь.

1 голос
/ 02 мая 2016

Вот моя версия, основанная непосредственно на ответе РХ.

Эта версия будет сбрасывать таймер, ЕСЛИ сеанс еще не истек.Таким образом, вы можете вставить весь этот блок прямо под 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();
        }
    }
1 голос
/ 10 апреля 2013

Все эти решения интересны и хорошо работают.

Но: что если вы находитесь в окне содержимого на основе фреймов?

Тогда есть два варианта:

  1. Перед выходом из системы или вызовом сценария выхода из системы должна быть достигнута верхняя часть страницы на основе фреймов (это можно сделать с помощью команды JavaScript, «разглаживающей» глубину текущей позиции в фрейме)

  2. В качестве альтернативы, для сброса в верхнюю позицию может быть вызван сценарий убийцы кадров или кадров, например

<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».

0 голосов
/ 13 сентября 2018

Я получил это простое решение, используя 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";
    }
}); 

С наилучшими пожеланиями.

...