¿Cómo hago caducar una sesión de PHP después de 30 minutos?

Resuelto Tom asked hace 54 años • 18 respuestas

Necesito mantener viva una sesión durante 30 minutos y luego destruirla.

Tom avatar Jan 01 '70 08:01 Tom
Aceptado

Debe implementar su propio tiempo de espera de sesión. Ambas opciones mencionadas por otros ( session.gc_maxlifetime y session.cookie_lifetime ) no son confiables. Explicaré las razones de ello.

Primero:

session.gc_maxlifetime
session.gc_maxlifetime especifica el número de segundos después de los cuales los datos se considerarán "basura" y se limpiarán. La recolección de basura se produce durante el inicio de la sesión.

Pero el recolector de basura solo se inicia con una probabilidad de session.gc_probability dividida por session.gc_divisor . Y utilizando los valores predeterminados para esas opciones (1 y 100 respectivamente), la probabilidad es sólo del 1%.

Bueno, simplemente podrías ajustar estos valores para que el recolector de basura se inicie con más frecuencia. Pero cuando se inicia el recolector de basura, verificará la validez de cada sesión registrada. Y eso es costoso.

Además, cuando se utilizan los archivos session.save_handler predeterminados de PHP , los datos de la sesión se almacenan en archivos en una ruta especificada en session.save_path . Con ese controlador de sesión, la antigüedad de los datos de la sesión se calcula en la fecha de la última modificación del archivo y no en la fecha del último acceso:

Nota: Si está utilizando el controlador de sesión basado en archivos predeterminado, su sistema de archivos debe realizar un seguimiento de los tiempos de acceso (atime). Windows FAT no lo hace, por lo que tendrá que idear otra forma de manejar la recolección de basura de su sesión si está atascado con un sistema de archivos FAT o cualquier otro sistema de archivos donde el seguimiento del tiempo no esté disponible. Desde PHP 4.2.3 se utiliza mtime (fecha de modificación) en lugar de atime. Por lo tanto, no tendrá problemas con los sistemas de archivos donde el seguimiento del tiempo no esté disponible.

Por lo tanto, también puede ocurrir que un archivo de datos de sesión se elimine mientras la sesión en sí todavía se considera válida porque los datos de la sesión no se actualizaron recientemente.

Y segundo:

session.cookie_lifetime
session.cookie_lifetime especifica la vida útil de la cookie en segundos que se envía al navegador. […]

Sí, eso es correcto. Esto sólo afecta la duración de la cookie y la sesión en sí puede seguir siendo válida. Pero es tarea del servidor invalidar una sesión, no del cliente. Entonces esto no ayuda en nada. De hecho, tener session.cookie_lifetime configurado en 0haría que la cookie de la sesión sea una cookie de sesión real que solo es válida hasta que se cierra el navegador.

Conclusión/mejor solución:

La mejor solución es implementar su propio tiempo de espera de sesión. Utilice una marca de tiempo simple que indique la hora de la última actividad (es decir, solicitud) y actualícela con cada solicitud:

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

La actualización de los datos de la sesión con cada solicitud también cambia la fecha de modificación del archivo de la sesión para que el recolector de basura no elimine la sesión prematuramente.

También puede utilizar una marca de tiempo adicional para regenerar periódicamente el ID de la sesión para evitar ataques a las sesiones, como la fijación de sesiones :

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
}

Notas:

  • session.gc_maxlifetimedebe ser al menos igual a la vida útil de este controlador de vencimiento personalizado (1800 en este ejemplo);
  • Si desea que la sesión caduque después de 30 minutos de actividad en lugar de después de 30 minutos desde el inicio , también deberá usar setcookiecon una caducidad de time()+60*30para mantener activa la cookie de sesión.
Gumbo avatar Aug 13 '2009 09:08 Gumbo

Forma sencilla de caducar la sesión de PHP en 30 minutos.

Nota: si desea cambiar la hora, simplemente cambie el 30 con la hora deseada y no cambie * 60: esto dará los minutos.


En minutos : (30 * 60 )
En días : (n * 24 * 60 * 60 ) n = nº de días


Iniciar sesió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!";
        }
    }
?>

Página de inicio.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
        }
    }
?>

Cerrar sesión.php

<?php
    session_start();
    session_destroy();
    header('Location: http://localhost/somefolder/login.php');
?>
Rafee avatar Sep 13 '2011 06:09 Rafee

¿Esto es para cerrar la sesión del usuario después de un tiempo determinado? Establecer la hora de creación de la sesión (o una hora de vencimiento) cuando se registra y luego verificar eso en cada carga de página podría manejar eso.

P.ej:

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

// later

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

Editar: tengo la sensación de que te refieres a otra cosa.

Puede descartar sesiones después de una determinada vida útil utilizando la session.gc_maxlifetimeconfiguración ini:

Editar: ini_set('session.gc_maxlifetime', 60*30);

Ross avatar Feb 06 '2009 13:02 Ross

Esta publicación muestra un par de formas de controlar el tiempo de espera de la sesión: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions

En mi humilde opinión, la segunda opción es una buena solución:

<?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);
    }
}
Pablo Pazos avatar Oct 07 '2014 02:10 Pablo Pazos

Bueno, entiendo que las respuestas anteriores son correctas pero están en el nivel de la aplicación, ¿por qué no usamos simplemente .htaccessel archivo para establecer el tiempo de caducidad?

<IfModule mod_php5.c>
    #Session timeout
    php_value session.cookie_lifetime 1800
    php_value session.gc_maxlifetime 1800
</IfModule>
Touqeer Shafi avatar Jul 15 '2015 06:07 Touqeer Shafi