Автоматический выход из системы после определенного времени [дубликат]

5 баллов в защиту Python
  1. Простота: поведение прост в следующем смысле: большинство людей попадают в эту ловушку только один раз, а не несколько раз.
  2. Согласованность: Python всегда передает объекты, а не имена. Параметр по умолчанию, очевидно, является частью заголовка функции (а не тела функции). Поэтому он должен оцениваться при времени загрузки модуля (и только при времени загрузки модуля, если не вложен), а не во время вызова функции.
  3. Полезность: Как указывает Фредерик Лунд в своем объяснении Значения параметров по умолчанию в Python ", текущее поведение может быть весьма полезно для расширенного программирования. (Используйте экономно.)
  4. Достаточная документация: в самой базовой документации Python, в руководстве, проблема громко объявляется как «Важное предупреждение» в первом разделе раздела раздела «Подробнее о определении функций» . Предупреждение даже использует жирный шрифт, который редко применяется за пределами заголовков. RTFM: прочитайте тонкое руководство.
  5. Мета-обучение: падение в ловушку на самом деле является очень полезным моментом (по крайней мере, если вы являетесь рефлексивным учеником), потому что впоследствии вы лучше поймете пункт «согласованность», выше, и это научит вас много о Python.

948
задан Mob 13 October 2011 в 08:38
поделиться

11 ответов

Вы должны реализовать собственный тайм-аут сеанса. Оба варианта, упомянутые другими ( session.gc_maxlifetime и session.cookie_lifetime ), ненадежны. Я объясню причины этого.

Сначала:

session.gc_maxlifetime session.gc_maxlifetime указывает количество секунд, после которых данные будут быть замеченным как «мусор» и очищен. Сбор мусора происходит во время начала сеанса.

Но сборщик мусора запускается только с вероятностью session.gc_probability , деленной на session.gc_divisor . И используя значения по умолчанию для этих параметров (1 и 100 соответственно), вероятность составляет всего 1%.

Ну, вы можете просто настроить эти значения, чтобы сборщик мусора запускался чаще. Но когда запускается сборщик мусора, он проверяет действительность для каждого зарегистрированного сеанса. И это дорого стоит.

Кроме того, при использовании файлов PHP по умолчанию session.save_handler данные сеанса хранятся в файлах по пути, указанному в session.save_path . С этим обработчиком сеанса возраст данных сеанса вычисляется на дату последней модификации файла, а не на последнюю дату доступа:

Примечание. Если вы используете обработчик сеанса по умолчанию, основанный на файлах, ваша файловая система должна отслеживать время доступа (atime). Windows FAT не так, вам придется придумать другой способ обработки мусора, собирающего вашу сессию, если вы застряли в файловой системе FAT или в любой другой файловой системе, где отслеживание атима недоступно. Начиная с PHP 4.2.3 он использовал mtime (измененная дата) вместо atime. Таким образом, у вас не будет проблем с файловыми системами, где отслеживание атима недоступно.

Таким образом, возможно, что файл данных сеанса удаляется, а сам сеанс по-прежнему считается действительным, поскольку

[blockquote>

session.cookie_lifetime session.cookie_lifetime указывает время жизни файла cookie в секундах, которое отправляется в браузер. [...]

Да, это так. Это влияет только на время жизни файла cookie, и сам сеанс может быть действительным. Но задача сервера - аннулировать сеанс, а не клиент. Так что это ничего не помогает. Фактически, если session.cookie_lifetime установлен на 0, сделайте cookie сеанса реальным сеансовым cookie , который действителен только до закрытия браузера.

Заключение / лучшее решение:

Лучшее решение - реализовать собственный тайм-аут сеанса. Используйте простую метку времени, которая обозначает время последнего действия (т. Е. Запрос) и обновляет его с каждым запросом:

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minutes ago
    session_unset();     // unset $_SESSION variable for the run-time 
    session_destroy();   // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

Обновление данных сеанса с каждым запросом также изменяет дату изменения файла сеанса, так что сеанс не удаляется сборщиком мусора преждевременно.

Вы также можете использовать дополнительную метку времени для регенерации идентификатора сеанса периодически, чтобы избежать атак на сеансы, такие как фиксация сеанса :

if (!isset($_SESSION['CREATED'])) {
    $_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
    // session started more than 30 minutes ago
    session_regenerate_id(true);    // change session ID for the current session and invalidate old session ID
    $_SESSION['CREATED'] = time();  // update creation time
}

Примечания:

  • session.gc_maxlifetime должно быть как минимум равно времени жизни этого пользовательского обработчика истечения (1800 в этом примере);
  • если вы хотите закончить сеанс после 30 минут активности вместо 30 минут с начала , вам также нужно будет использовать setcookie с истечением срока действия time()+60*30 ], чтобы сохранить файл cookie сессии.
1524
ответ дан Lode 21 August 2018 в 16:18
поделиться
  • 1
    Как вы можете изменить это, если хотите проверить «неактивное время»? Другими словами, пользователь входит в систему, и пока они продолжают использовать сайт, он не выйдет из системы. Однако, если они неактивны в течение 30 минут, они выйдут из системы? – Metropolis 9 August 2010 в 17:29
  • 2
    @Metropolis: используйте что-то вроде $_SESSION['LAST_ACTIVITY'], похожего на $_SESSION['CREATED'], где вы сохраняете время последнего действия пользователя, но обновляете это значение с каждым запросом. Теперь, если разница этого времени с текущим временем больше, чем 1800 секунд, сеанс не использовался более 30 минут. – Gumbo 9 August 2010 в 17:37
  • 3
    @Metropolis: session_unset делает то же самое, что и $_SESSION = array(). – Gumbo 9 August 2010 в 20:06
  • 4
    @Gumbo - Я немного смущен, разве вы не используете свой код в сочетании с ini_set('session.gc-maxlifetime', 1800)? В противном случае ваша информация о сеансе может быть уничтожена, пока ваш сеанс все еще должен быть действительным, по крайней мере, если настройка ini является стандартной 24-минутной. Или я чего-то не хватает? – jeroen 27 October 2010 в 22:05
  • 5
    @jeron: Да, вы должны. Но обратите внимание, что session.gc_maxlifetime зависит от последней даты изменения файла, если используется обработчик сохранения сеанса files. Таким образом, session.gc_maxlifetime должно быть как минимум равно времени жизни этого пользовательского обработчика истечения срока действия. – Gumbo 27 October 2010 в 22:13

Сохраните временную метку в сеансе


<?php    
$user = $_POST['user_name'];
$pass = $_POST['user_pass'];

require ('db_connection.php');

// Hey, always escape input if necessary!
$result = mysql_query(sprintf("SELECT * FROM accounts WHERE user_Name='%s' AND user_Pass='%s'", mysql_real_escape_string($user), mysql_real_escape_string($pass));

if( mysql_num_rows( $result ) > 0)
{
    $array = mysql_fetch_assoc($result);    

    session_start();
    $_SESSION['user_id'] = $user;
    $_SESSION['login_time'] = time();
    header("Location:loggedin.php");            
}
else
{
    header("Location:login.php");
}
?>

Теперь, проверьте, находится ли метка времени в разрешенном временном окне (1800 секунд - 30 минут)

<?php
session_start();
if( !isset( $_SESSION['user_id'] ) || time() - $_SESSION['login_time'] > 1800)
{
    header("Location:login.php");
}
else
{
    // uncomment the next line to refresh the session, so it will expire after thirteen minutes of inactivity, and not thirteen minutes after login
    //$_SESSION['login_time'] = time();
    echo ( "this session is ". $_SESSION['user_id'] );
    //show rest of the page and all other content
}
?>
6
ответ дан Alpesh Rathod 21 August 2018 в 16:18
поделиться

Использование timestamp ...

<?php
if (!isset($_SESSION)) {
    $session = session_start();
} 
if ($session && !isset($_SESSION['login_time'])) {
    if ($session == 1) {
        $_SESSION['login_time']=time();
        echo "Login :".$_SESSION['login_time'];
        echo "<br>";
        $_SESSION['idle_time']=$_SESSION['login_time']+20;
        echo "Session Idle :".$_SESSION['idle_time'];
        echo "<br>";
    } else{
        $_SESSION['login_time']="";
    }
} else {
    if (time()>$_SESSION['idle_time']){
        echo "Session Idle :".$_SESSION['idle_time'];
        echo "<br>";
        echo "Current :".time();
        echo "<br>";
        echo "Session Time Out";
        session_destroy();
        session_unset();
    } else {
        echo "Logged In<br>";
    }
}
?>

Я использовал 20 секунд для истечения сеанса с использованием метки времени.

Если вам нужно 30 минут добавить 1800 (30 минут в секундах) ...

0
ответ дан azro 21 August 2018 в 16:18
поделиться

Используйте session_set_cookie_params funciton для этого.

Необходимо вызвать эту функцию до вызова session_start().

Попробуйте это:

$lifetime = strtotime('+30 minutes', 0);

session_set_cookie_params($lifetime);

session_start();

См. Больше в: http://php.net/manual/function.session-set-cookie-params.php

11
ответ дан edwardmp 21 August 2018 в 16:18
поделиться

Пожалуйста, используйте следующий блок кода в вашем файле include, который загружается на всех страницах.

$expiry = 1800 ;//session expiry required after 30 mins
    if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
        session_unset();
        session_destroy();
    }
    $_SESSION['LAST'] = time();
5
ответ дан lnepal 21 August 2018 в 16:18
поделиться

В этом сообщении показано несколько способов контроля таймаута сеанса: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions

IMHO второй вариант является хорошим решением:

<?php
/***
 * Starts a session with a specific timeout and a specific GC probability.
 * @param int $timeout The number of seconds until it should time out.
 * @param int $probability The probablity, in int percentage, that the garbage 
 *        collection routine will be triggered right now.
 * @param strint $cookie_domain The domain path for the cookie.
 */
function session_start_timeout($timeout=5, $probability=100, $cookie_domain='/') {
    // Set the max lifetime
    ini_set("session.gc_maxlifetime", $timeout);

    // Set the session cookie to timout
    ini_set("session.cookie_lifetime", $timeout);

    // Change the save path. Sessions stored in teh same path
    // all share the same lifetime; the lowest lifetime will be
    // used for all. Therefore, for this to work, the session
    // must be stored in a directory where only sessions sharing
    // it's lifetime are. Best to just dynamically create on.
    $seperator = strstr(strtoupper(substr(PHP_OS, 0, 3)), "WIN") ? "\\" : "/";
    $path = ini_get("session.save_path") . $seperator . "session_" . $timeout . "sec";
    if(!file_exists($path)) {
        if(!mkdir($path, 600)) {
            trigger_error("Failed to create session save path directory '$path'. Check permissions.", E_USER_ERROR);
        }
    }
    ini_set("session.save_path", $path);

    // Set the chance to trigger the garbage collection.
    ini_set("session.gc_probability", $probability);
    ini_set("session.gc_divisor", 100); // Should always be 100

    // Start the session!
    session_start();

    // Renew the time left until this session times out.
    // If you skip this, the session will time out based
    // on the time when it was created, rather than when
    // it was last used.
    if(isset($_COOKIE[session_name()])) {
        setcookie(session_name(), $_COOKIE[session_name()], time() + $timeout, $cookie_domain);
    }
}
18
ответ дан Pablo Pazos 21 August 2018 в 16:18
поделиться
if (isSet($_SESSION['started'])){
    if((mktime() - $_SESSION['started'] - 60*30) > 0){
        //Logout, destroy session, etc.
    }
}
else {
    $_SESSION['started'] = mktime();
}
113
ответ дан Peter Mortensen 21 August 2018 в 16:18
поделиться
  • 1
    Сочетание логики и презентации не рекомендуется в этот день и в возрасте, когда MVC является нормой. – stillstanding 9 May 2012 в 17:54
  • 2
    Итак, если вам нужно собрать это вручную, то какое gc_maxlifetime точно используется для ??? – xcy7e 웃 10 July 2014 в 07:23
  • 3
    Может быть, мне не хватает чего-то элементарного в сеансах, но что хорошего это делает, если сеансы уничтожаются каждые 30 минут ОС? – user 20 August 2014 в 23:38
  • 4
    @ По-прежнему говорите для себя [улыбка] Я рассматриваю MVC как мерзость. – user 20 August 2014 в 23:39
  • 5
    Является ли MVC хорошей идеей, даже когда проект небольшой, с одним программистом? Я чувствую, что должен делать свои собственные проекты в модели MVC (или решить проблему THEN, сделав ее MVC), но с отсутствием опыта работы с MVC он просто становится ментальным блоком «Как мне сделать этот MVC? & Quot; и отвлечение от исходной цели / задачи, требующей решения. – MrVimes 27 July 2018 в 09:36

Выйти из системы через заданное время? Установка времени создания сеанса (или времени истечения) при его регистрации, а затем проверка того, что на каждой загрузке страницы можно было бы это обработать.

Например:

$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());

// later

if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
    unset($_SESSION['example']);
}

Изменить: I У вас есть чувство, что вы имеете в виду что-то еще.

Вы можете выполнять сеансы после определенной продолжительности жизни, используя настройку session.gc_maxlifetime ini:

Изменить : ini_set ('session.gc_maxlifetime', 60 * 30);

33
ответ дан Ted Cohen 21 August 2018 в 16:18
поделиться
  • 1
    session.gc-maxlifetime, вероятно, лучший способ. – Powerlord 6 February 2009 в 14:45
  • 2
    Есть некоторые проблемы с временем работы cookie сеанса, в первую очередь, он полагается на клиента, чтобы обеспечить его соблюдение. Время существования файла cookie позволяет клиенту очистить бесполезные / истекшие файлы cookie, его не следует путать с чем-либо связанным с безопасностью. – Jacco 15 May 2012 в 13:32
  • 3
    Это gc_maxlifetime или gc-maxlifetime. Поддерживает ли это символы подчеркивания и дефисов? – Mike Causer 17 August 2012 в 09:25

На самом деле это просто с такой функцией, как следующая. Он использует имя таблицы базы данных «сеансы» с полями «id» и «time».

Каждый раз, когда пользователь снова посещает ваш сайт или службу, вы должны вызвать эту функцию, чтобы проверить, имеет ли ее возвращаемое значение TRUE. Если это FALSE, пользователь истек, и сеанс будет уничтожен (Примечание. Эта функция использует класс базы данных для подключения и запроса базы данных, конечно, вы также можете сделать это внутри своей функции или что-то в этом роде):

function session_timeout_ok() {
    global $db;
    $timeout = SESSION_TIMEOUT; //const, e.g. 6 * 60 for 6 minutes
    $ok = false;
    $session_id = session_id();
    $sql = "SELECT time FROM sessions WHERE session_id = '".$session_id."'";
    $rows = $db->query($sql);
    if ($rows === false) {
        //Timestamp could not be read
        $ok = FALSE;
    }
    else {
        //Timestamp was read succesfully
        if (count($rows) > 0) {
            $zeile = $rows[0];
            $time_past = $zeile['time'];
            if ( $timeout + $time_past < time() ) {
                //Time has expired
                session_destroy();
                $sql = "DELETE FROM sessions WHERE session_id = '" . $session_id . "'";
                $affected = $db -> query($sql);
                $ok = FALSE;
            }
            else {
                //Time is okay
                $ok = TRUE;
                $sql = "UPDATE sessions SET time='" . time() . "' WHERE session_id = '" . $session_id . "'";
                $erg = $db -> query($sql);
                if ($erg == false) {
                    //DB error
                }
            }
        }
        else {
            //Session is new, write it to database table sessions
            $sql = "INSERT INTO sessions(session_id,time) VALUES ('".$session_id."','".time()."')";
            $res = $db->query($sql);
            if ($res === FALSE) {
                //Database error
                $ok = false;
            }
            $ok = true;
        }
        return $ok;
    }
    return $ok;
}
9
ответ дан Torsten Barthel 21 August 2018 в 16:18
поделиться

Ну, я понимаю, что ответы на ошибки верны, но они находятся на уровне приложений, почему бы нам просто не использовать файл .htaccess для установки времени истечения?

<IfModule mod_php5.c>
    #Session timeout
    php_value session.cookie_lifetime 1800
    php_value session.gc_maxlifetime 1800
</IfModule>
15
ответ дан Touqeer Shafi 21 August 2018 в 16:18
поделиться
  • 1
    @ Ответ Лоде дает прекрасное объяснение, почему этот ответ ненадежный не должен использоваться. – emix 21 August 2017 в 06:22
115
ответ дан Mr. Nobody 1 November 2018 в 09:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: