Как истечь сеанс PHP через 30 минут?

Мне нужно сохранить сеанс в течение 30 минут, а затем уничтожить его.

11 ответов


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

первый:

сессии.gc_maxlifetime
сессии.gc_maxlifetime задает время в секундах, после которой данные будут рассматриваться как "мусор" и убрали. Сбор мусора происходит во время запуска сеанса.

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

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

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

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

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

и второе:

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

Да, правильно. Это влияет только на время жизни cookie и сам сеанс может все еще быть действительным. Но это задача сервера аннулировать сеанс, а не клиента. Так что это ничему не поможет. На самом деле, имея сессии.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 сеанса активным.

простой способ истечения срока действия сеанса PHP за 30 минут.

Примечание : Если вы хотите изменить время, просто измените 30 с желаемым временем и не меняют * 60: это дает минут.


в минутах: (30 * 60)
В днях : (n * 24 * 60 * 60 ) n = нет дней


логин.в PHP

<?php
    session_start();
?>

<html>
    <form name="form1" method="post">
        <table>
            <tr>
                <td>Username</td>
                <td><input type="text" name="text"></td>
            </tr>
            <tr>
                <td>Password</td>
                <td><input type="password" name="pwd"></td>
            </tr>
            <tr>
                <td><input type="submit" value="SignIn" name="submit"></td>
            </tr>
        </table>
    </form>
</html>

<?php
    if (isset($_POST['submit'])) {
        $v1 = "FirstUser";
        $v2 = "MyPassword";
        $v3 = $_POST['text'];
        $v4 = $_POST['pwd'];
        if ($v1 == $v3 && $v2 == $v4) {
            $_SESSION['luser'] = $v1;
            $_SESSION['start'] = time(); // Taking now logged in time.
            // Ending a session in 30 minutes from the starting time.
            $_SESSION['expire'] = $_SESSION['start'] + (30 * 60);
            header('Location: http://localhost/somefolder/homepage.php');
        } else {
            echo "Please enter the username or password again!";
        }
    }
?>

Домашняя страница.в PHP

<?php
    session_start();

    if (!isset($_SESSION['luser'])) {
        echo "Please Login again";
        echo "<a href='http://localhost/somefolder/login.php'>Click Here to Login</a>";
    }
    else {
        $now = time(); // Checking the time now when home page starts.

        if ($now > $_SESSION['expire']) {
            session_destroy();
            echo "Your session has expired! <a href='http://localhost/somefolder/login.php'>Login here</a>";
        }
        else { //Starting this else one [else1]
?>
            <!-- From here all HTML coding can be done -->
            <html>
                Welcome
                <?php
                    echo $_SESSION['luser'];
                    echo "<a href='http://localhost/somefolder/logout.php'>Log out</a>";
                ?>
            </html>
<?php
        }
    }
?>

выход из системы.в PHP

<?php
    session_start();
    session_destroy();
    header('Location: http://localhost/somefolder/login.php');
?>

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

например:

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

// later

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

Edit: у меня такое чувство, что ты имеешь в виду что-то еще.

вы можете отказаться от сеансов после определенного срока службы с помощью session.gc_maxlifetime ini параметр:

Edit: сессия безопасность ('.gc_maxlifetime', 60*30);


этот пост показывает несколько способов управления таймаутом сеанса: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);
    }
}

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

<IfModule mod_php5.c>
    #Session timeout
    php_value session.cookie_lifetime 1800
    php_value session.gc_maxlifetime 1800
</IfModule>

if (isSet($_SESSION['started'])){
    if((mktime() - $_SESSION['started'] - 60*30) > 0){
        //Logout, destroy session, etc.
    }
}
else {
    $_SESSION['started'] = mktime();
}

использовать session_set_cookie_paramsфункции для этого.

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

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

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

session_set_cookie_params($lifetime);

session_start();

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


это на самом деле легко с функцией, как показано ниже. Он использует имя таблицы базы данных "сеансы" с полями " id " и "время".

каждый раз, когда пользователь снова посещает ваш сайт или службу, вы должны вызвать эту функцию, чтобы проверить, является ли ее возвращаемое значение 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;
}

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


<?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
}
?>

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

$expiry = 1800 ;//session expiry required after 30 mins
    if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
        session_unset();
        session_destroy();
    }
    $_SESSION['LAST'] = time();

использование метки времени...

<?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 секунд, чтобы истечь сеанс с помощью timestamp.

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