setcoo - read cookies in php




Come faccio a scadere una sessione PHP dopo 30 minuti? (8)

Devo mantenere una sessione in vita per 30 minuti e quindi distruggerla.


Scadenza della sessione PHP in 30 minuti.

Nota: se si desidera modificare l'ora, basta cambiare il 30 con il tempo desiderato e non cambiare * 60: questo darà i minuti.

In minuti: (30 * 60)
In giorni: (n * 24 * 60 * 60) n = no dei giorni

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

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');
?>

È necessario implementare un timeout di sessione personalizzato. Entrambe le opzioni menzionate da altri ( session.gc_maxlifetime e session.cookie_lifetime ) non sono affidabili. Spiegherò le ragioni per questo.

Primo:

session.gc_maxlifetime
session.gc_maxlifetime specifica il numero di secondi dopo i quali i dati verranno visualizzati come "garbage" e ripuliti. La raccolta dei dati inutili si verifica durante l'avvio della sessione.

Ma il garbage collector viene avviato solo con una probabilità di session.gc_probability divisa per session.gc_divisor . E usando i valori predefiniti per queste opzioni (rispettivamente 1 e 100), la possibilità è solo dell'1%.

Bene, puoi semplicemente regolare questi valori in modo che il garbage collector venga avviato più spesso. Ma quando viene avviato il garbage collector, controllerà la validità di ogni sessione registrata. E questo è costoso.

Inoltre, quando si utilizzano i file session.save_handler predefiniti di PHP, i dati della sessione vengono archiviati in file in un percorso specificato in session.save_path . Con quel gestore di sessione, l'età dei dati della sessione viene calcolata sulla data dell'ultima modifica del file e non sull'ultima data di accesso:

Nota: se si utilizza il gestore di sessione basato su file predefinito, il proprio filesystem deve tenere traccia dei tempi di accesso (atime). FAT di Windows non è così che dovrai trovare un altro modo per gestire la raccolta dei dati inutili se sei bloccato con un file system FAT o con qualsiasi altro file system in cui il monitoraggio Atime non è disponibile. Dal PHP 4.2.3 ha usato mtime (data modificata) invece di atime. Quindi, non avrai problemi con i filesystem in cui il monitoraggio atime non è disponibile.

Quindi potrebbe anche accadere che un file di dati di sessione venga eliminato mentre la sessione stessa è ancora considerata valida poiché i dati di sessione non sono stati aggiornati di recente.

E secondo:

session.cookie_lifetime
session.cookie_lifetime specifica la durata del cookie in secondi che viene inviata al browser. [...]

Sì, è giusto. Ciò influisce solo sulla durata del cookie e la sessione stessa potrebbe essere ancora valida. Ma è compito del server invalidare una sessione, non il client. Quindi questo non aiuta nulla. Infatti, avere session.cookie_lifetime impostato su 0 renderebbe il cookie della sessione un cookie di sessione reale che è valido solo fino alla chiusura del browser.

Conclusione / soluzione migliore:

La soluzione migliore è implementare un timeout di sessione personalizzato. Utilizzare un timestamp semplice che denoti l'ora dell'ultima attività (ad es. Richiesta) e aggiornarlo ad ogni richiesta:

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

L'aggiornamento dei dati di sessione ad ogni richiesta modifica anche la data di modifica del file di sessione in modo che la raccolta non venga rimossa prematuramente dal garbage collector.

È anche possibile utilizzare un timestamp aggiuntivo per rigenerare periodicamente l'ID sessione per evitare attacchi su sessioni come la fissazione della sessione :

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
}

Gli appunti:

  • session.gc_maxlifetime dovrebbe essere almeno uguale alla durata di questo gestore di scadenza personalizzato (1800 in questo esempio);
  • se si desidera scadere la sessione dopo 30 minuti di attività anziché dopo 30 minuti dall'inizio , sarà necessario utilizzare setcookie con una scadenza di time()+60*30 per mantenere attivo il cookie di sessione.

Bene capisco che le risposte precedenti sono corrette ma sono a livello di applicazione, perché non usiamo semplicemente il file .htaccess per impostare il tempo di scadenza?

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

In realtà è facile con una funzione come la seguente. Utilizza il nome della tabella del database "sessioni" con i campi "id" e "time".

Ogni volta che l'utente visita nuovamente il tuo sito o servizio, dovresti richiamare questa funzione per verificare se il suo valore di ritorno è VERO. Se è FALSE l'utente è scaduto e la sessione verrà distrutta (Nota: questa funzione utilizza una classe di database per connettersi e interrogare il database, ovviamente si potrebbe anche farlo all'interno della propria funzione o qualcosa del genere):

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

Questo post mostra un paio di modi per controllare il timeout della sessione: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions

IMHO la seconda opzione è una bella soluzione:

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

Usa il funciton session_set_cookie_params per farlo.

È necessario chiamare questa funzione prima della chiamata session_start() .

Prova questo:

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

session_set_cookie_params($lifetime);

session_start();

Vedi di più su: http://php.net/manual/function.session-set-cookie-params.php


Utilizza il seguente blocco di codice nel file di inclusione caricato in ogni pagina.

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

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




cookies