Pregunta ¿Cómo expiraré una sesión PHP después de 30 minutos?


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


933
2018-02-06 13:14


origen


Respuestas:


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

Primero:

session.gc_maxlifetime
session.gc_maxlifetime especifica la cantidad de segundos después de los cuales los datos se verán como "basura" y se limpiarán. La recolección de basura ocurre durante el inicio de la sesión.

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

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

Además, al usar el valor predeterminado de PHP session.save_handler archivos, 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 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 manejador 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 de atime no esté disponible. Desde PHP 4.2.3, ha utilizado mtime (fecha de modificación) en lugar de atime. Por lo tanto, no tendrá problemas con los sistemas de archivos donde el seguimiento de atime no está disponible.

Por lo tanto, también puede ocurrir que se elimine un archivo de datos de sesión mientras que la sesión en sí 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 duración de la cookie en segundos que se envía al navegador. [...]

Si, eso es correcto Esto solo afecta la duración de la cookie y la sesión misma puede ser válida. Pero la tarea del servidor es invalidar una sesión, no el cliente. Entonces esto no ayuda en nada. De hecho, teniendo session.cookie_lifetime ajustado a 0 haría que la cookie de la sesión sea real cookie de sesión eso solo es válido hasta que el navegador esté cerrado.

Conclusión / mejor solución:

La mejor solución es implementar un tiempo de espera de sesión propio. Use una marca de tiempo simple que denota la hora de la última actividad (es decir, la 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 sesión para que el recolector de elementos no elimine prematuramente la sesión.

También puede usar un sello de tiempo adicional para regenerar el ID de sesión periódicamente para evitar ataques en sesiones como fijación de sesión:

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_maxlifetime debe ser al menos igual al tiempo de vida de este controlador de caducidad personalizado (1800 en este ejemplo);
  • si desea caducar la sesión después de 30 minutos de actividad en lugar de después de 30 minutos desde el comienzo, también necesitarás usar setcookie con un vencimiento de time()+60*30 para mantener la cookie de sesión activa.

1519
2017-08-13 09:24



Forma simple de expirar la sesión de PHP en 30 minutos.

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


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


Login.php

<?php
    session_start();
?>

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

<?php
    if ($_POST['submit1']) {
        $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!";
        }
    }
?>

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

LogOut.php

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

113
2017-09-13 06:39



¿Esto es para desconectar al usuario después de un tiempo establecido? Establecer el tiempo de creación de la sesión (o un tiempo de caducidad) cuando está registrado, y luego verificar que 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 quieres decir algo más.

Puede eliminar sesiones después de una vida útil determinada utilizando el session.gc_maxlifetime entorno ini:

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


33
2018-02-06 13:20



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);
    }
}

18
2017-10-07 02:31



Bueno, entiendo que las respuestas anteriores son correctas pero están en el nivel de la aplicación, ¿por qué no simplemente usamos .htaccess 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>

16
2017-07-15 06:16



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

11
2018-02-06 13:21



Utilizar el session_set_cookie_paramsfunciton para hacer esto.

Es necesario llamar a esta función antes session_start() llamada.

Prueba esto:

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

session_set_cookie_params($lifetime);

session_start();

Ver más en: http://php.net/manual/function.session-set-cookie-params.php


11
2018-05-13 12:43



En realidad es fácil con una función como la siguiente. Utiliza las 'sesiones' del nombre de la tabla de la base de datos con los campos 'id' y 'time'.

Cada vez que el usuario visite nuevamente su sitio o servicio, debe invocar esta función para verificar si su valor de retorno es VERDADERO. Si es FALSO, el usuario ha expirado y la sesión se destruirá (Nota: Esta función utiliza una clase de base de datos para conectarse y consultar la base de datos, por supuesto también puede hacerlo dentro de su función o algo así):

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
2018-01-24 08:40



Almacenar una marca de tiempo en la sesión


<?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");
}
?>

Ahora, compruebe si la marca de tiempo está dentro de la ventana de tiempo permitida (1800 segundos son 30 minutos)

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

5
2018-05-21 11:20



Utilice el siguiente bloque de código en su archivo de inclusión que se cargó en cada página.

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

5
2017-08-26 06:55



Usando la marca de tiempo ...

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

He usado 20 segundos para caducar la sesión usando la marca de tiempo.

Si necesita 30 minutos, agregue 1800 (30 minutos en segundos) ...


0
2018-03-21 10:40