Bir PHP oturumunu 30 dakika sonra nasıl dolarım?


1047

Bir oturumu 30 dakika canlı tutmam ve sonra yok etmem gerekiyor.


35
Lütfen oturum süresini ayarlamak için en az iki ayarın ve belki de üç ayarın çok önemli olduğunu unutmayın. Kesinlikle çok önemli olan ikisi session.gc_maxlifetime ve session.cookie_lifetime'dır (burada 0, bazı uzun sayılarla aynı değildir). Uzun sürelere izin vermenin% 100 kesinliği için, oturum dosyalarının varsayılan olarak depolandığı / tmp dizininde değişen OS denetimli temizleme süresi nedeniyle session.save_path öğesini ayarlamak da gerekebilir.
Kzqai

1
Oturumu neden sona erdirmek istediğini anlamıyorum. Kullanıcının oturumu kapatmadan bilgisayarından ayrıldığından endişe ediyorsanız ve yetkisiz bir kullanıcı bilgisayarını devralırsa, sitenizdeki oturumun sona ermesi, korsanının kurbanın diskteki dosyalarına erişmesini engellemez.
Gqqnbig

Burada ne istediğini belli değil. Sabit bir hareketsizlik zaman aşımı uygulamak istediğinizi mi (şu anda PHP, session.gc_maxlifetime değerinden daha uzun bir süredir dokunulmamış bir oturumu kullanmanıza izin veriyor) veya oturumu ne olursa olsun oturumu 30 dakika ile sınırlamak istediğiniz anlamına mı geliyor? hareketsizlik? Açıkçası, burada kabul edilen cevabın her iki sorun için de oldukça kötü bir tavsiye olduğunu düşünüyorum - her iki durumda da mantık özel bir oturum işleyicisi ile uygulanmalıdır.
symcbean

Yanıtlar:


1663

Kendi oturum zaman aşımını uygulamalısınız. Başkaları tarafından belirtilen her iki seçenek de ( session.gc_maxlifetime ve session.cookie_lifetime ) güvenilir değildir. Bunun nedenlerini açıklayacağım.

İlk:

session.gc_maxlifetime
session.gc_maxlifetime , verilerin 'çöp' olarak görüleceği ve temizleneceği saniye sayısını belirtir. Çöp toplama, oturumun başlatılması sırasında oluşur.

Ama çöp toplayıcı sadece bir olasılık ile başlatılır session.gc_probability bölü session.gc_divisor . Ve bu seçenekler için varsayılan değerleri kullanarak (sırasıyla 1 ve 100), şans sadece% 1'dir.

Çöp toplayıcının daha sık başlatılması için bu değerleri kolayca ayarlayabilirsiniz. Ancak çöp toplayıcı başlatıldığında, kayıtlı her oturumun geçerliliğini kontrol eder. Ve bu masraflıdır.

Ayrıca, PHP'nin varsayılan session.save_handler dosyalarını kullanırken, oturum verileri session.save_path içinde belirtilen yoldaki dosyalarda saklanır . Bu oturum işleyicisiyle, oturum verilerinin yaşı dosyanın son değişiklik tarihinde değil, son değişiklik tarihinde hesaplanır:

Not: Varsayılan dosya tabanlı oturum işleyicisini kullanıyorsanız, dosya sisteminizin erişim sürelerini (atime) izlemesi gerekir. Bir FAT dosya sistemi veya atime izlemenin mevcut olmadığı başka bir dosya sistemi ile sıkışmışsanız, Windows FAT oturumunuzu toplamak için başka bir yol bulmanız gerekmeyecektir. PHP 4.2.3'ten beri atime yerine mtime (değiştirilme tarihi) kullanmıştır. Dolayısıyla, atime izlemenin yapılamadığı dosya sistemlerinde sorun yaşamayacaksınız.

Dolayısıyla, oturum verileri yakın zamanda güncellenmediği için, oturumun kendisi hala geçerli kabul edilirken bir oturum veri dosyasının silinmesi de oluşabilir.

Ve ikinci:

session.cookie_lifetime
session.cookie_lifetime , çerezin ömrünü tarayıcıya gönderilen saniye cinsinden belirtir. [...]

Evet bu doğru. Bu yalnızca çerezin ömrünü etkiler ve oturumun kendisi hala geçerli olabilir. Ancak, istemciyi değil oturumu geçersiz kılmak sunucunun görevidir. Yani bu hiçbir şeye yardımcı olmaz. Aslında, session.cookie_lifetime değerinin ayarlanmış olması, oturumun çerezini yalnızca tarayıcı kapatılana kadar geçerli olan 0gerçek bir oturum çerezidir .

Sonuç / en iyi çözüm:

En iyi çözüm kendi oturum zaman aşımını uygulamaktır. Son etkinliğin zamanını (yani istek) gösteren basit bir zaman damgası kullanın ve her istekle güncelleyin:

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

Oturum verilerinin her istekle güncellenmesi, oturumun çöp toplayıcı tarafından erken kaldırılmaması için oturum dosyasının değişiklik tarihini de değiştirir.

Oturum sabitleme gibi oturumlara yapılan saldırıları önlemek için oturum kimliğini düzenli olarak yeniden oluşturmak için ek bir zaman damgası da kullanabilirsiniz :

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
}

Notlar:

  • session.gc_maxlifetime en azından bu özel süre sonu işleyicisinin ömrüne eşit olmalıdır (bu örnekte 1800);
  • başlangıcından bu yana 30 dakika sonra değil 30 dakikalık bir etkinlikten sonra oturumu sona erdirmek istiyorsanız , oturum çerezinin etkin kalması için de bir sona erme tarihi kullanmanız gerekir .setcookietime()+60*30

3
"Etkin olmayan zamanı" kontrol etmek isterseniz bunu nasıl değiştirebilirsiniz? Başka bir deyişle, kullanıcı oturum açar ve siteyi kullanmaya devam ettikleri sürece oturumu kapatmaz. Ancak 30 dakika boyunca hareketsiz kalırlarsa çıkışları kapanır mı?
Metropolis

14
@Metropolis: Kullanıcının son etkinliğinin zamanını sakladığınız yere $_SESSION['LAST_ACTIVITY']benzer bir şey kullanın $_SESSION['CREATED'], ancak bu değeri her istekle güncelleyin. Şimdi o zamanın şimdiki zamanla olan farkı 1800 saniyeden büyükse, oturum 30 dakikadan fazla bir süredir kullanılmamaktadır.
Gumbo

3
@Metropolis: session_unsetile aynı şeyi yapar $_SESSION = array().
Gumbo

14
@Gumbo - Biraz kafam karıştı, kodunuzu birlikte kullanmamalısınız ini_set('session.gc-maxlifetime', 1800)? Aksi takdirde, en azından ini ayarı standart 24 dakika ise, oturum bilgilerinizin hala geçerli olması gerekiyorken oturum bilgileriniz yok edilebilir. Yoksa bir şey mi kaçırıyorum?
jeroen

10
@jeron: Evet, yapmalısın. Ancak session.gc_maxlifetimefiles öğesinin , oturum kaydetme işleyicisi kullanılıyorsa dosyanın son değişiklik tarihine bağlı olduğunu unutmayın . Bu yüzden session.gc_maxlifetime en azından bu özel son kullanma eylemcisinin yaşam süresine eşit olmalıdır.
Gumbo

135

30 dakika içinde PHP oturumu sona erme basit yolu.

Not: Saati değiştirmek isterseniz, 30'u istediğiniz zamanla değiştirin ve * 60'ı değiştirmeyin: bu dakikaları verecektir.


Dakikalar içinde: (30 * 60)
Günlerde: (n * 24 * 60 * 60) n = gün sayısı


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

42
MVC'nin norm olduğu bu gün ve yaşta mantık ve sunumu birleştirmek tavsiye edilmez.
bcosca

Belki oturumlar hakkında temel bir şey eksik ama işletim sistemleri her 30 dakikada bir yok edilirse bu ne işe yarar?

25
@stillstanding Kendiniz için konuşun [gülümse] MVC'yi iğrenç olarak görüyorum.

2
MVC, proje küçük olsa bile tek bir programcıyla iyi bir fikir mi? MVC modelinde kendi projelerimi yapmam gerektiğini hissediyorum (ya da MVC yapmasından sonra sorunu çözmek) ama MVC ile deneyim eksikliği sadece zihinsel bir blok haline gelir "Bu MVC nasıl yapabilirim?" ve bir çözüm gerektiren başlangıçtaki amaç / problemden sapma.
MrVimes

@stillstanding başka bir söz Login.phpiçeriği kötü içerikten SONRA başlıklarda gönderilir olmasıdır.
machineaddict

43

Bu, belirli bir süre sonra kullanıcının oturumunu kapatmak mıdır? Oturum oluşturulduğunda oturum oluşturma süresini (veya süre sonu süresini) ayarlama ve ardından her sayfa yüklemesinde bunun işlenebileceğini kontrol etme.

Örneğin:

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

// later

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

Edit: Yine başka bir şey demek istediğinizi hissediyorum.

session.gc_maxlifetimeİni ayarını kullanarak belirli bir kullanımdan sonra oturumları kaldırabilirsiniz :

Düzenleme: ini_set ('session.gc_maxlifetime', 60 * 30);


1
session.gc-maxlifetime muhtemelen en iyi yoldur.
Powerlord

2
Oturum çerezi ömrüyle ilgili bazı sorunlar vardır, en önemlisi, istemcinin zorlaması için kullanılır. Çerez ömrü, müşterinin yararsız / süresi dolmuş çerezleri temizlemesine izin vermek için vardır, güvenlikle ilgili herhangi bir şeyle karıştırılmamalıdır.
Jacco

Öyle mi gc_maxlifetimeyoksa gc-maxlifetime. Hem alt çizgileri hem de kısa çizgileri destekliyor mu?
Mike Causer

24

Bu yayın, oturum zaman aşımını kontrol etmenin birkaç yolunu gösterir: http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions

IMHO ikinci seçenek güzel bir çözümdür:

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

19

Eh, yukarıdaki cevapların doğru olduğunu ancak uygulama düzeyinde olduğunu anlıyorum, neden sadece son kullanma .htaccesssüresini ayarlamak için dosyayı kullanmıyoruz ?

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

1
@ Lode'nin cevabı, bu cevabın neden güvenilmez olduğu konusunda mükemmel bir açıklama sağlar.
emix

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


11

Aşağıdaki gibi bir işlevle aslında kolaydır. 'İd' ve 'time' alanlarıyla veritabanı tablo adı 'sessions' kullanır.

Kullanıcı sitenizi veya hizmetinizi tekrar ziyaret ettiğinde, dönüş değerinin DOĞRU olup olmadığını kontrol etmek için bu işlevi çağırmalısınız. YANLIŞ ise kullanıcının süresi dolmuşsa ve oturum yok edilecektir (Not: Bu işlev, veritabanını bağlamak ve sorgulamak için bir veritabanı sınıfı kullanır, elbette bunu işlevinizin içinde veya bunun gibi bir şey içinde de yapabilirsiniz):

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

Oturumda bir zaman damgası saklama


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

Şimdi, zaman damgasının izin verilen zaman aralığında olup olmadığını kontrol edin (1800 saniye 30 dakikadır)

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

8

Lütfen içerme dosyanızda her sayfaya yüklenen aşağıdaki kod bloğunu kullanın.

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

1

Bu sınıfı 30 dakika boyunca kullan

class Session{
    public static function init(){
        ini_set('session.gc_maxlifetime', 1800) ;
        session_start();
    }
    public static function set($key, $val){
        $_SESSION[$key] =$val;
    }
    public static function get($key){
        if(isset($_SESSION[$key])){
            return $_SESSION[$key];
        } else{
            return false;
        }
    }
    public static function checkSession(){
        self::init();
        if(self::get("adminlogin")==false){
            self::destroy();
            header("Location:login.php");
        }
    }
    public static function checkLogin(){
        self::init();
        if(self::get("adminlogin")==true){
            header("Location:index.php");
        }
    }
    public static function destroy(){
        session_destroy();
        header("Location:login.php");
    }
}

0

Zaman damgası kullanılıyor ...

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

Zaman damgasını kullanarak oturumu sona erdirmek için 20 saniye kullandım .

30 dakikaya ihtiyacınız varsa 1800 ekleyin (saniyede 30 dakika) ...


0

Alternatif olarak bir DB'yi doğrudan kullanabilirsiniz. Ben chk_lgn çağırmak yapmak için bir DB işlevi kullanın.

Oturum açıp açmadıklarını görmek için oturum açma denetimlerini kontrol edin ve bunu yaparken, çekin tarih zaman damgasını kullanıcının db satırında / sütununda son etkin olarak ayarlar.

Orada da zaman kontrolü yapıyorum. Bu işlevi her sayfa için kullandığım için bu benim için çalışıyor.

PS Gördüğüm hiç kimse saf bir DB çözümü önermemişti.



-1

Sadece geçerli saati saklayın ve karşılaştırarak 30 dakikayı aşarsa geçerli oturumu yok edin.


Bunu değerlendirdiğiniz tek zaman, oturumu kullanırken değil mi?
Eric Kramer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.