PHP'de bir çerezin ömrü nasıl belirlenir? Oturumlar. Operasyonun ayrıntılı açıklaması ve mekanizmanın açıklanması. Oturum değişkenlerini kullanarak kullanıcı hareketsizliğini kontrol etme

  • 20.06.2020

Web sunucusu istemciyle kalıcı bir bağlantı kurmaz ve her istek, öncekilerle herhangi bir bağlantı olmaksızın yeni bir istek olarak işlenir.
Yani, ne aynı ziyaretçiden gelen istekleri takip edebilir ne de bireysel sayfaların görünümleri arasında onun değişkenlerini kaydedebilirsiniz. Seanslar bu iki sorunu çözmek için icat edildi.
Aslında oturumlar kısaca, bir tarayıcıyı benzersiz bir şekilde tanımlamanıza ve bu tarayıcı için oturum değişkenlerinin saklandığı sunucuda bir dosya oluşturmanıza olanak tanıyan bir mekanizmadır.

Böyle bir mekanizmaya olan ihtiyacı ayrıntılı olarak anlatmayacağım. Bunlar, bir e-mağazadaki alışveriş sepeti, yetkilendirme gibi ders kitabı vakalarının yanı sıra bir sitenin etkileşimli bölümlerini spam'den korumak gibi tamamen önemsiz olmayan sorunlardır.

Prensip olarak, PHP'de yerleşik olan kadar işlevsel olmasa da özünde benzer olan kendi oturum analogunuzu oluşturmak oldukça kolaydır. Çerezlerde ve veritabanında.
Bir komut dosyası isteğinde bulunurken belirli bir ada sahip bir çerezin alınıp alınmadığına bakarız. Çerez yoksa ayarlayın ve kullanıcı verilerini içeren yeni bir satırı veritabanına yazın. Bir çerez varsa, veri tabanından verileri okuruz. Başka bir istekle veri tabanından eski kayıtları siliyoruz ve artık hazır bir oturum mekanizmamız var. Hiç de zor değil. Ancak yerleşik oturum mekanizmasının kullanılmasını tercih edilebilir kılan bazı nüanslar vardır.

Yalnızca ilki etkinleştirilmişse, oturumun başlangıcında (her çağrı oturum_başlangıcı()) istemci için bir çerez ayarlanır. Tarayıcı bu çerezi sonraki her istekte doğru şekilde döndürür ve PHP'nin bir oturum tanımlayıcısı vardır. Tarayıcı çerezleri döndürmezse sorunlar başlar. Bu durumda, tanımlayıcı içeren bir çerez almadan PHP her zaman yeni bir oturum başlatacak ve mekanizma çalışmayacaktır.

Yalnızca ikincisi etkinleştirilirse çerez ayarlanmaz. Ve olan da budur, bunun için aslında yerleşik oturum mekanizmasını kullanmaya değer. Betik işini yaptıktan ve sayfa tamamen oluşturulduktan sonra PHP tüm sayfayı tarar ve her bağlantıya ve her forma bir oturum tanımlayıcısı ekler. Şunun gibi bir şeye benziyor:
Dizin dönüşür
Dizin
ve formlara gizli bir alan eklenir

Ve tarayıcı, herhangi bir bağlantıya tıkladığınızda veya formdaki bir düğmeye tıkladığınızda, isteğe ihtiyacımız olan değişkeni, yani oturum tanımlayıcıyı gönderecektir!
Açık nedenlerden ötürü, tanımlayıcı yalnızca göreceli bağlantılara eklenir.

Teorik olarak, çerezler ve veritabanıyla ilgili ev yapımı oturumlarımızda, tüm bağlantılara manuel olarak kimlik aktarımı atayabiliriz ve ardından kendi oturumlarımız çerezlerden bağımsız olarak çalışacaktır. Ama bu işi başka birinin yapmasının daha keyifli olduğunu kabul ediyor musunuz? ;-)

PHP'nin son sürümlerinde varsayılan olarak her iki seçenek de etkindir. PHP bunu nasıl ele alıyor? Cook her zaman sergilenir. Ve bağlantılar yalnızca PHP'nin oturum tanımlayıcısı olan bir çerez algılamaması durumunda otomatik olarak tamamlanır. Bu oturum sırasında kullanıcı siteyi ilk kez ziyaret ettiğinde çerez yerleştirilerek bağlantılar tamamlanır. Bir sonraki istekte, eğer çerezler destekleniyorsa, PHP çerezi görür ve bağlantıları tamamlamayı durdurur. Çerezler çalışmazsa, PHP bağlantılara doğru şekilde kimlik eklemeye devam eder ve oturum kaybolmaz.
Çerezlerin etkin olduğu kullanıcılar, kimlik içeren uzun bağlantıyı yalnızca bir kez görecektir.

Vay be. Kimlik aktarımı tamamlandı.
Artık geriye kalan tek şey veri dosyasını sunucu tarafında ona bağlamaktır.
PHP bunu bizim için yapacak. yazmanız yeterli
oturum_başlangıç();
$_SESSION [ "test" ]= "Merhaba dünya!" ;

Ve PHP test değişkenini bu oturumla ilişkili dosyaya yazacaktır.
Burada çok önemli bir not var.
Sıralamak $_SESSION- özel.
Aslında çeşitli scriptlerde kullanılabilir hale getirmek istediğimiz değişkenleri içerir.
Bir oturuma bir değişken yerleştirmek için onu $_SESSION dizi öğesine atamanız yeterlidir.
Değerini elde etmek için aynı öğeye erişmeniz yeterlidir. Aşağıda bir örnek olacak.

PHP aynı zamanda çöp toplama işlemini de gerçekleştirerek güncel olmayan dosyaları kaldırır. Veri kodlamanın ve diğer birçok gerekli şeyin yanı sıra. Bu bakım sonucunda seanslarla çalışmak oldukça basittir.
Burada aslında oturumların nasıl çalıştığı örneğine geliyoruz.
Çok küçük bir örnek:
oturum_başlangıç();

Eko "Bu sayfayı güncellediniz". $_SESSION["sayaç"]++. " bir kere. " ;
Eko "
güncelleme" ;
?>

Oturumda sayaç değişkenimiz olup olmadığını kontrol ediyoruz, yoksa 0 değeriyle oluşturup değerini görüntüleyip bir artırıyoruz. Artan değer oturuma yazılacak ve betiğin bir sonraki çağrılışında değişken 1 değerine sahip olacak ve bu böyle devam edecek.
Her şey çok basit.

Sitenin herhangi bir sayfasındaki oturum değişkenlerine erişebilmek için oturumlara ihtiyaç duyduğumuz HER dosyanın başına SADECE BİR (!) satır yazmanız gerekir:
oturum_başlangıç();
Daha sonra $_SESSION dizisinin öğelerine erişin. Örneğin, bir yetkilendirme kontrolü şuna benzer:
oturum_başlangıç();
if ($_SESSION [ "yetkili" ]<> 1 ) {
başlık("Konum: /auth.php");
çıkış;
}

Değişkenleri bir oturumdan kaldırma.
Register_globals=off'unuz varsa, yazmanız yeterli
unset($_SESSION[ "var" ]);
O zaman değilse yakın onunla yazmam lazım
session_unregister("var");

Oturumlarla çalışmaya çalışırken PHP'nin ürettiği en yaygın hatalar şunlardır:
İkisi
Uyarı: Oturum çerezi gönderilemiyor - başlıklar zaten gönderildi
Uyarı: Oturum önbellek sınırlayıcısı gönderilemiyor - başlıklar zaten gönderildi

aynı sebepten kaynaklanıyorsa çözümü bu başlıkta anlatılıyor
Üçüncü,
Uyarı: open(/tmp\sess_SID, O_RDWR) başarısız oldu: Satır numarasındaki full_script_path'te böyle bir dosya veya dizin (2) yok(daha önce şöyle görünüyordu Uyarı: Oturum verileri (dosyalar) yazılamadı. Lütfen session.save_path'in mevcut ayarının doğru olduğunu doğrulayın (/tmp)),
İngilizce'den çevrilmişse, sorunu ayrıntılı olarak açıklar: php.ini'de belirtilen, oturum dosyalarının yazıldığı dizinin yolu mevcut değil. Bu hata düzeltilmesi en kolay olanıdır. Sadece var olan ve yazılabilir bir dizini kaydedin; örneğin,
session.save_path = c:\windows\temp
Ve bundan sonra Apache'yi yeniden başlatmayı unutmayın.

Görünen o ki, insan zekasının hiçbir sınırı yok ve bu nedenle şunu açıklamak zorunda kalıyorum:
üçüncü hatayla ilgili bir mesaj (dizin bulunamıyor) KAÇINILMAZ bir şekilde ilk ikisinin ortaya çıkmasına neden olacaktır, çünkü hata mesajı tarayıcıya ve başlıklara çıktıktan sonra kullanılamaz. Bu nedenle, erken bir sonuç aramak için acele etmeyin, önce doğru yolu yazın!

Oturumlarla çalışırken bir sonraki en yaygın sorun, Register_globals'ın ağır mirasıdır. $_SESSION dizisinin indeksleriyle eşleşen kod değişkenlerine ad VERMEYİN!
Register_globals=on ile değerler birbirinin üzerine yazacak ve kafanız karışacaktır.
Register_globals=off ise başka bir hata görünecektir: "Betiğiniz muhtemelen PHP 4.2.3'e kadar var olan bir oturum yan etkisine dayanıyor.", eğer betiğin değeri olmayan bir oturum değişkeni ve genel bir değişkeni varsa aynı isim . Bundan kurtulmak için, değişkenleri kullanmadan önce her zaman başlatmalısınız (veya en azından varlığını kontrol etmelisiniz) ve $_SESSION dizisinin dizinleriyle örtüşen genel değişken adları vermemelisiniz.

Çalışmıyorsa ancak hiçbir mesaj görüntülenmiyorsa, komut dosyasının en başına TÜM hataların ekranda görüntülenmesinden sorumlu iki satır ekleyin - hataların olması oldukça olasıdır, ancak bunları görmüyorsunuz.
ini_set("display_errors", 1);
error_reporting(E_ALL);

veya error_log'daki hataları görün. Genel olarak hata mesajlarının görüntülenmesi konusu bu makalenin kapsamı dışındadır, bu nedenle en azından onları görebildiğinizden emin olun. Bu bölümde hataları bulma hakkında biraz daha bilgi edinebilirsiniz.

Herhangi bir hata olmadığından eminseniz ancak verilen örnek yine de çalışmıyorsa, bu durumda PHP, kimliğin URL yoluyla aktarılmasına izin vermiyor olabilir, ve çerezler bazı nedenlerden dolayı çalışmıyor.
Kurabiyelerin ne olduğuna bak.
Genel olarak, oturumlarınız çalışmıyorsa, önce oturum tanımlayıcısını manuel olarak iletmeyi deneyin, yani bir bağlantı oluşturun ve ona bir tanımlayıcı atayın:
oturum_başlangıç();
if (!isset($_SESSION [ "sayaç" ])) $_SESSION [ "sayaç" ]= 0 ;
Eko "Bu sayfayı güncellediniz". $_SESSION["sayaç"]++. " bir kere.

güncelleme" ;
?>

Ancak, session.use_only_cookies yönergesinin etkin olmadığından emin olmalısınız; bu, URL aracılığıyla iletilmişse PHP'nin oturum kimliğini kabul etmesini engeller.

Bu örnek işe yaramazsa sorun ya önemsizdir yazım hataları(oturumlarla ilgili "sorunların" yarısı yanlış yazılmış değişken adından kaynaklanmaktadır) veya PHP'nin çok eski bir sürümünde: oturumlar için destek sürüm 4.0'da ortaya çıktı ve dizi $_SESSION- 4.1'de (Bundan önce kullanılıyordu) $HTTP_SESSION_VARS).
Çalışıyorsa sorun çerezlerdedir. Sunucunun tarayıcıya ne tür bir çerez ayarladığını ve tarayıcının bunu döndürüp döndürmediğini izleyin. Tarayıcı ile sunucu arasındaki HTTP başlıklarının değişimine bakarak arama yapmak oldukça faydalıdır.
Çerezlerin nasıl çalıştığına dair bir açıklama zaten çok uzun olan bu metnin kapsamı dışındadır, ancak en azından sunucunun tanımlayıcı içeren bir çerez gönderdiğinden ve tarayıcının bunu geri döndürdüğünden emin olun. Ve aynı zamanda tanımlayıcılar birbiriyle örtüşüyor =)
Çerezin ayarlanması şöyle görünmelidir
Set-Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6;
veya nasıl
Set-Cookie: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6; yol=/
(komut dosyasını kök dizinden talep etmiyorsanız)
Sunucu yanıtı şöyle görünmelidir
Çerez: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6
veya
Çerez: PHPSESSID=prlgdfbvlg5fbsbshch6hj0cq6; b=b
tarayıcının oturum kimliği dışında çerezler döndürmesi durumunda.

Tarayıcı çerezleri döndürmezse çerezlerin çalışıp çalışmadığını kontrol edin.
Eriştiğiniz alan adının normal bir isme sahip olduğundan (en az bir nokta içeren ve alt çizgi gibi yasa dışı karakterler içermeyen) emin olun ve tarayıcınızın önbelleğini temizleyin; bunlar, çerezlerin çalışmamasının iki ana nedenidir.

Buradaki örnek çalışıyor ancak kendi kodunuz çalışmıyorsa, sorun açıkça oturumlarda değil algoritmadadır. Değişkeni nerede kaybettiğinizi arayın, örneği buradan adım adım aktarın ve betiğinizin hatalarını ayıklayın.

Başlık yönlendirmesini veya JavaScript gezinmesini kullanırsanız başka bir sorun ortaya çıkabilir.
Gerçek şu ki, PHP otomatik olarak oturum tanımlayıcısını yalnızca aşağıdaki gibi bağlantılara ekler:
, ancak bunu başlıklar, JavaScript ve meta etiketler için yapmaz.
Bu nedenle, tanımlayıcıyı örneğin şu şekilde manuel olarak eklemeniz gerekir:
başlık("Konum: /script.php?" . oturum_adı(). "=" . oturum_id());

Ayrıca çok nadir görülen ve nereden geldiği tamamen belirsiz olan bir sorun da session.save_handler ayarının dosyalardan farklı bir değere sahip olmasıdır. Eğer durum böyle değilse düzeltin.

Emniyet
Oturum güvenliği geniş bir konudur. Bu nedenle birkaç ana noktaya odaklanacağım.
En ders kitabı olan, tanımlayıcıyı adres çubuğundan geçirmemektir. Bu php.ini'de bile yazılmıştır, ancak bu oturumların işlevselliğini sınırlar. Bu tavsiyeye uymaya karar verirseniz session.use_trans_sid = 0'a ek olarak session.use_only_cookies = 1 değerini de unutmayın.
Oturumu bir IP adresine bağlamanız önerilir: bu şekilde, tanımlayıcı çalınırsa kötü adam çoğu durumda onu kullanamayacaktır.
Oturum dosyalarını kaydetmek için kendi dizininizi ayarlamanıza olanak tanıyan session.save_path yönergesini kullanmanız önerilir. Bu, bunların sunucunun varsayılan paylaşılan geçici dizininde saklanmasından daha güvenlidir.

Ek Bilgiler:

  • Çerezlere ek olarak oturum mekanizması sayfaların önbelleğe alınmasını yasaklayan başlıklar da gönderir (aynı önbellek sınırlayıcı). Html için bu doğru ve gereklidir. Ancak yetkilendirmeyi denetleyen bir komut dosyası kullanarak bir dosya göndermeye çalıştığınızda Internet Explorer dosyayı indirmeyi reddeder. Bu başlık yüzünden. Arama
    session_cache_limiter("özel");
    Oturuma başlamadan önce sorunu çözmelisiniz.
  • Göründüğü kadar tuhaf ama dizide $_SESSION Sayısal dizinleri kullanamazsınız - $_SESSION [ 1 ], $_SESSION [ "10" ]- oturumlar çalışmayacaktır.
  • 4.2 ve 5.0 sürümleri arasında session.use_trans_sid'i kullanarak ayarlamak mümkün değildi. ini_set(). 5.0'dan itibaren bu yine mümkün.
  • Çerezin 4.3.3 sürümünden önce PHP, yalnızca oturum başlatıldığında istekte hiçbir tanımlayıcı bulunmadığında bir çerez gönderiyordu. Artık her çağrıya bir çerez gönderiliyor oturum_başlangıcı()

    Oturumları kullanarak yetkilendirme örneği
    Yukarıdakilerin tümünü küçük bir örnekle açıklayalım:
    Auth.php dosyasını oluşturalım:
    if (isset($_POST [ "kimlik_adı" ]))
    {
    $sql = "SELECT * FROM user WHERE name=?s";
    $satır = $db -> getRow($sql, $_POST["kimlik_adı"]);
    if ($satır && şifre_verify ($_POST [ "yetki_şifresi" ], $satır [ "şifre" ])) (
    $_SESSION [ "kullanıcı_kimliği" ] = $satır [ "kimlik" ];
    }
    başlık("Konum: http://" . $_SERVER [ "HTTP_HOST" ] $_SERVER [ "REQUEST_URI" ]);
    çıkış;
    }

    if (isset($_GET [ "işlem" ]) VE $_GET [ "işlem" ]== "çıkış" ) (
    oturum_başlangıç();
    session_destroy();
    başlık("Konum: http://" . $_SERVER [ "HTTP_HOST" ] "/" );
    çıkış;
    }

    if (!isset($_SESSION [ "kullanıcı_kimliği" ])) (
    ?>








    çıkış;
    }

    Artık tek yapmanız gereken, tüm korumalı komut dosyalarına satırı yazmak
    "auth.php" gerektirir;
    Bu örnekte, oturumun zaten başlatıldığı ve MySQL ile güvenli ve rahat çalışma için Class kullanılarak veritabanına bir bağlantı oluşturulduğu varsayılmaktadır. Ayrıca, önerilen parola_hash işlevi kullanılarak parolanın karma hale getirildiğini de varsayar.
    Korumalı bir dosya örneği:

    oturum_başlangıç();
    "safemysql.class.php" ekleyin;
    $db = yeni güvenlimysql ([ "db" => "test" ]);
    "auth.php"yi ekleyin;
    ?>
    gizli

    çıkış Yap

    Aman Tanrım! Çok Yararlı Bağlantılar:
    http://www.php.net/manual/ru/ref.session.php - resmi belgelerde PHP'de oturum desteği hakkında en son ve en güncel bilgiler ve ayrıca çok sayıda kullanıcı yorumu. Kesinlikle okunması tavsiye edilir.
    http://phpclub.ru/manrus/f/ref.session.html - Alexander Pyramidin tarafından çevrilen belgelerden bu bölümün Rusçaya ÇOK eski bir çevirisi.
    http://phpclub.ru/detail/article/sessions
    "Seanslarla İlgili Gerçek" adlı acıklı başlığı olan bir makale. Kararsız bir izlenim bırakıyor. Yazar başlangıçta oturum mekanizmasından ÇOK net bir şekilde bahsediyor ancak makalenin sonunda sunduğu yöntemler tamamen belirsiz.

    Siteden Dmitry Borodin'in bir ders kitabı makalesi
    http://php.spb.ru/ kesinlikle tavsiye edilmez.
    Arkadaşlar, bu çok eski. Yalnızca gerçeklere dayalı yanlışlıklar içermekle kalmıyor, aynı zamanda PHP'deki oturumlar uzun süredir çalışmıyor.
    Bunun için Dima'ya çok teşekkürler, bu Rusça oturumlarla ilgili ilk makaleydi, ondan kendim çalıştım ama şimdi onu hak ettiği bir dinlenmeye göndermem gerekiyor.
    Ayrıca internette yer alan ve yıllardır güncellenmeyen birçok makale de ne yazık ki güncelliğini kaybetmiş durumda.

  • PHP $_SESSION değişkenlerinin çalışma süresi ve bunun sonucunda web uygulamalarının etkinliği oturumun süresine bağlıdır. Örneğin bir kullanıcı sisteme giriş yapmışsa, kullanıcı adı ve şifresini tekrar girmek zorunda kalmadan ne kadar süre aktif kalabileceği bu parametreye bağlıdır.

    Oturum yaşam sürelerini ayarlamanın farklı yolları vardır. Örnek olarak Linux işletim sistemini kullanarak bunu anlamaya çalışalım.

    Oturumun ömrü nasıl öğrenilir?

    Kurulumdan önce mevcut duruma bakmaya değer. Bunu yapmanın birkaç yöntemi vardır:

    1. PHP komutunu kullanarak sunucuda

    php -i | grep oturumu

    Oturumlarla ilgili parametrelerin bir listesini alıyoruz. İlgileniyoruz:

    • session.cookie_lifetime => 0 => 0
    • session.gc_maxlifetime => 1440 => 1440

    Bu değerler varsayılan değerdir. cookie_lifetime => 0 tarayıcı kapatılıncaya kadar çerezlerin etkisinden bahsediyor, bu parametreyi belirli bir değere ayarlarsanız, oturum aktifken oturum kesilecektir, bu nedenle sıfırda bırakmak daha iyidir.

    2. PHP'nin ini_get fonksiyonunu kullanma

    $maxlifetime = ini_get("session.gc_maxlifetime");
    $cookielifetime = ini_get("session.cookie_lifetime");

    Echo $maxlifetime;
    echo $çerezömrüboyu;

    systemctl apache2'yi yeniden başlat || systemctl httpd'yi yeniden başlat

    * systemd olmayan Linux versiyonlarında bu komutu kullanırız hizmet apache2 yeniden başlat veya hizmet httpd yeniden başlat.

    FastCGI (PHP-FPM) kullanırsak:

    .htaccess dosyası aracılığıyla yapılandırma

    Bu dosya, web yöneticisinin bazı web sunucusu ayarlarını yönetmesine olanak tanır. Düzenlemek için site dosyalarına erişmeniz gerekir. PHP işleyicisi Apache değilse, örneğin NGINX + PHP-FPM ise yöntem çalışmayacaktır. Yine de bir yol da var (daha fazlası aşağıda).

    .htaccess dosyasına aşağıdakileri ekliyoruz:

    php_value session.gc_maxlifetime 86400
    php_value session.cookie_lifetime 0

    * gördüğünüz gibi parametreler php.ini aracılığıyla yapılandırıldığındakilerle aynıdır.

    Yukarıda belirtildiği gibi Apache kullanılmadığı takdirde yöntem çalışmayacaktır. Ancak kurulum sunucuda yapılabilir (yine uygun erişime sahip olmamız gerekir).

    Web sunucusu yapılandırma dosyasını örneğin php-fpm'de açın:

    vi /etc/php-fpm.d/www.conf

    ve düzenleyin/ekleyin:

    php_value = 86400
    php_value = 0

    Daha sonra servisi yeniden başlatıyoruz:

    systemctl php-fpm'yi yeniden başlat || hizmet php-fpm yeniden başlatma

    Uygulama kodunda parametre ayarlama

    Bu yöntem, farklı portal sayfalarının farklı oturum yaşam sürelerine sahip olması gerektiğinde yararlı olabilir. Bunu yapmak için PHP'nin ini_set ve session_set_cookie_params işlevlerini kullanabilirsiniz, örneğin:

    Ini_set("session.gc_maxlifetime", 86400);
    ini_set("session.cookie_lifetime", 0);
    session_set_cookie_params(0);

    Oturum_başlangıcı();

    Bir oturumu açmadan önce işlevler çağrılmalıdır (session_start).

    Uygulamada bir oturum ayarlama

    Bazı uygulamalar ayarları geçersiz kılabilir. Bu durumda oturum ömrünü program parametrelerinde ayarlamanız gerekir. Her uygulamanın, kendi başınıza çözmeniz gereken kendi ayarları vardır. Bitrix CMS'de oturum ayarlama örneğini ele alalım.

    Hadi gidelim Kullanıcı grubu- bir grup seçin - Emniyet. “Oturum ömrü (dakika)” parametresini bulun ve saati ayarlayın, örneğin 1440 (dakika cinsinden 24 saat).

    Oturumlar otomatik olarak nasıl yenilenir

    Bir oturumun belirli bir süre için düzenlenmesi ve belirli bir saatte bitmesi kullanıcının aktif oturumunun kesintiye uğramasına neden olabilir. Ziyaretçinin sayfayı yenilemesi durumunda oturum süresinin otomatik olarak uzatılması çok daha kullanışlı olur. Bunun için yukarıdaki tüm örneklerde 0 olarak ayarladığımız cookie_lifetime parametresi bulunmaktadır.

    Cookie_lifetime değerini 86400 olarak ayarlarsak 24 saat sonra oturum sonlandırılacaktır. Bu her zaman uygun değildir.

    Oturumu kontrol etme ve kesme ihtiyacı varsa PHP işlevini kullanabilirsiniz. session_destroy().

    Oturum dosyası depolama yolu

    Oturum dosyalarının depolama konumu parametre ile belirtilir session.save_path aynı zamanda hayatın zamanı da öyle. Varsayılan olarak yol kullanılabilir /var/lib/php/sessions.

    Bu önemli bir parametredir; eğer web sunucusunun bu dizine yazma izinleri yoksa, bu durum oturumların saklanamamasına yol açacak ve bu da uygulamalardan beklenmeyen sonuçlara yol açacaktır.

    Selamlar sevgili topluluk.

    Öncelikle çok faydalı bir kaynak için teşekkür etmek istiyorum. Burada birçok kez ilginç fikirler ve pratik tavsiyeler buldum.

    Bu makalenin amacı PHP'de oturum kullanmanın tuzaklarını vurgulamaktır. Elbette PHP belgeleri ve çok sayıda örnek var ve bu makalenin tam bir rehber olması amaçlanmamıştır. Oturumlarla çalışmanın bazı nüanslarını ortaya çıkarmak ve geliştiricileri gereksiz zaman israfından korumak için tasarlanmıştır.

    Oturum kullanmanın en yaygın örneği elbette kullanıcı yetkilendirmesidir. Yeni görevler ortaya çıktıkça yavaş yavaş geliştirmek için en temel uygulamayla başlayalım.

    (Yerden ve zamandan tasarruf etmek için burada güzel bir sınıf hiyerarşisine, kapsamlı hata yönetimine ve diğer iyi özelliklere sahip tam teşekküllü bir test uygulaması oluşturmak yerine örneklerimizi yalnızca oturum işlevleriyle sınırlayacağız).

    function startSession() ( // Oturum zaten başlatılmışsa, yürütmeyi durdurun ve TRUE'yu döndürün // (php.ini ayarlar dosyasındaki session.auto_start parametresi devre dışı bırakılmalıdır - varsayılan değer) if (session_id()) dönerse true; else return session_start(); // Not: Sürüm 5.3.0'dan önce, session_start() işlevi bir hata olsa bile TRUE değerini döndürüyordu. // 5.3.0'dan önceki bir sürümü kullanıyorsanız, ek bir kontrol yapın. session_id() // session_start() fonksiyonunu çağırdıktan sonra destroySession() ( if (session_id()) ( // Aktif bir oturum varsa, oturum çerezlerini silin, setcookie(session_name(), session_id(), time() )-60*60*24); // ve oturumu yok edin session_unset( );

    Not: Okuyucunun PHP oturumları hakkında temel bilgiye sahip olduğu varsayılmaktadır, dolayısıyla burada session_start() ve session_destroy() işlevlerinin çalışma prensiplerini ele almayacağız. Giriş formunun düzeni ve kullanıcı kimlik doğrulaması görevleri makalenin konusuyla ilgili değildir, bu nedenle bunları da atlayacağız. Size, sonraki her istekte kullanıcıyı tanımlamak için, başarılı oturum açma anında, kullanıcı tanımlayıcısını, sonraki tüm isteklerde kullanılabilecek bir oturum değişkeninde (örneğin, kullanıcı kimliği olarak adlandırılan) saklamamız gerektiğini hatırlatmama izin verin. oturumun ömrü. Ayrıca startSession() fonksiyonumuzun sonucunun işlenmesini uygulamak da gereklidir. İşlev FALSE değerini döndürürse, oturum açma formunu tarayıcıda görüntüleyin. İşlev TRUE değerini döndürdüyse ve yetkili kullanıcının tanımlayıcısını (bizim durumumuzda - kullanıcı kimliği) içeren bir oturum değişkeni mevcutsa, yetkili kullanıcının sayfasını görüntüleyin (hata yönetimi hakkında daha fazla bilgi için 2013-06- tarihli eke bakın) 07, oturum değişkenleri bölümünde).

    Buraya kadar her şey açık. Kullanıcı hareketsizliği kontrolünü (oturum zaman aşımı) uygulamanız, birden fazla kullanıcının tek bir tarayıcıda aynı anda çalışmasına olanak sağlamanız ve ayrıca oturumları yetkisiz kullanıma karşı korumanız gerektiğinde sorular başlar. Bu konuya aşağıda tekrar değinilecektir.

    Yerleşik PHP araçlarını kullanarak kullanıcı hareketsizliğini izleme

    Kullanıcılara yönelik her türlü konsolun geliştiricileri arasında sıklıkla ortaya çıkan ilk soru, kullanıcının herhangi bir işlem yapmaması durumunda oturumun otomatik olarak sonlandırılmasıdır. Bunu PHP'nin yerleşik yeteneklerini kullanarak yapmaktan daha kolay bir şey yoktur. (Bu seçenek özellikle güvenilir veya esnek değildir, ancak bütünlüğü sağlamak için bunu dikkate alacağız).

    Function startSession() ( // Kullanıcı hareketsizliği zaman aşımı (saniye cinsinden) $sessionLifetime = 300; if (session_id()) return true; // Çerez ömrünü ayarlayın ini_set("session.cookie_lifetime", $sessionLifetime); // If user hareketsizlik zaman aşımı ayarlandı, sunucudaki oturum ömrünü ayarlayın // Not: Bir üretim sunucusu için, bu parametrelerin php.ini dosyasında önceden ayarlanması önerilir if ($sessionLifetime) ini_set("session.gc_maxlifetime", $sessionLifetime if (session_start(); )) ( setcookie(session_name(), session_id(), time()+$sessionLifetime); true değerini döndürür; ) aksi halde false değerini döndürür)

    Birkaç açıklama. Bildiğiniz gibi PHP, istek başlığında tarayıcının gönderdiği çerez adı ile hangi oturumun başlatılması gerektiğini belirler. Tarayıcı da bu çerezi, session_start() işlevinin yerleştirdiği sunucudan alır. Tarayıcı çerezinin süresi dolmuşsa, istekte gönderilmeyecektir; bu, PHP'nin hangi oturumun başlatılacağını belirleyemeyeceği ve bunu yeni bir oturum oluşturuyormuş gibi değerlendireceği anlamına gelir. Kullanıcının hareketsizlik zaman aşımına eşit olarak ayarlanan PHP ayarları parametresi session.gc_maxlifetime, PHP oturumunun ömrünü belirler ve sunucu tarafından kontrol edilir. Oturum ömrünü kontrol etmek şu şekilde çalışır (burada PHP'de en yaygın ve varsayılan seçenek olarak oturumları geçici dosyalarda saklama örneğini ele alıyoruz).

    Yeni bir oturum oluşturulduğunda, PHP ayarları parametresi session.save_path'te oturum depolama dizini olarak ayarlanan dizinde sess_ adlı bir dosya oluşturulur. , Nerede - oturum tanımlayıcı. Daha sonra, her istekte, halihazırda var olan bir oturumun başlatılması sırasında PHP bu dosyanın değiştirilme zamanını günceller. Böylece, sonraki her istekte PHP, geçerli zaman ile oturum dosyasındaki son değişiklik zamanı arasındaki farka göre, oturumun aktif olup olmadığını veya ömrünün zaten dolmuş olup olmadığını belirleyebilir. (Eski oturum dosyalarını silme mekanizması bir sonraki bölümde daha ayrıntılı olarak ele alınmaktadır.)

    Not: Burada session.gc_maxlifetime parametresinin bir sunucudaki (daha kesin olarak tek bir ana PHP işlemindeki) tüm oturumlara uygulandığına dikkat edilmelidir. Uygulamada bu, sunucuda birden fazla site çalışıyorsa ve her birinin kendi kullanıcı eylemsizliği zaman aşımı varsa, bu parametrenin sitelerden birinde ayarlanmasının diğer siteler için de ayarlanmasına yol açacağı anlamına gelir. Aynı şey paylaşılan barındırma için de geçerlidir. Bu durumu önlemek için aynı sunucu içerisinde her site için ayrı oturum dizinleri kullanılır. Oturum dizininin yolunu ayarlamak, php.ini ayarlar dosyasındaki session.save_path parametresi kullanılarak veya ini_set() işlevi çağrılarak yapılır. Bundan sonra her sitenin oturumları ayrı dizinlerde saklanacak ve sitelerden birinde ayarlanan session.gc_maxlifetime parametresi yalnızca o oturum için geçerli olacaktır. Özellikle kullanıcı hareketsizliğini izlemeye yönelik daha esnek bir seçeneğe sahip olduğumuz için bu durumu ayrıntılı olarak ele almayacağız.

    Oturum değişkenlerini kullanarak kullanıcı hareketsizliğini kontrol etme

    Görünüşe göre önceki seçenek, tüm basitliğine rağmen (yalnızca birkaç ek kod satırı) ihtiyacımız olan her şeyi veriyor. Peki ya her istek kullanıcı faaliyetinin sonucu olarak kabul edilemiyorsa? Örneğin, bir sayfada, sunucudan güncellemeleri almak için periyodik olarak AJAX isteğinde bulunan bir zamanlayıcı bulunur. Böyle bir istek kullanıcı etkinliği olarak kabul edilemez, yani bu durumda oturum ömrünün otomatik olarak uzatılması doğru değildir. Ancak, session_start() işlevi her çağrıldığında PHP'nin oturum dosyasının değişiklik zamanını otomatik olarak güncellediğini biliyoruz; bu, herhangi bir isteğin oturum ömrünün uzamasına yol açacağı ve kullanıcının hareketsizlik zaman aşımının asla gerçekleşmeyeceği anlamına gelir. Ayrıca, önceki bölümde yer alan, session.gc_maxlifetime parametresinin inceliklerine ilişkin son not, bazıları için çok kafa karıştırıcı ve uygulanması zor görünebilir.

    Bu sorunu çözmek için, yerleşik PHP mekanizmalarının kullanımını bırakacağız ve kullanıcının etkinlik dışı kalma süresini kendi başımıza kontrol etmemizi sağlayacak birkaç yeni oturum değişkeni tanıtacağız.

    Function startSession($isUserActivity=true) ( ​​$sessionLifetime = 300; if (session_id()) return true; // Tarayıcıyı kapatmadan önce çerez ömrünü ayarlayın (sunucu tarafındaki her şeyi kontrol edeceğiz) ini_set("session.txt) cookie_lifetime", 0) ; if (! session_start()) return false; $t = time(); if ($sessionLifetime) ( // Kullanıcının hareketsizlik zaman aşımı ayarlanmışsa, // kullanıcının son aktivitesinden bu yana geçen süreyi kontrol edin // (son isteğin zamanı) son aktivite oturum değişkeni güncellendiğinde) if (isset($_SESSION["lastactivity"]) && $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( // If kullanıcının son etkinliğinden bu yana geçen süre, / / ​​etkinlik dışı kalma zaman aşımından daha büyük, bu da oturumun süresinin dolduğu ve oturumun sonlandırılması gerektiği anlamına geliyor destroySession(); else ( // Zaman aşımı henüz gerçekleşmediyse, // ve if istek kullanıcı etkinliğinin bir sonucu olarak geldi, // lastactivity değişkenini mevcut olanın değeriyle güncelleyin time; // böylece oturum süresini başka bir sessionLifetime saniye kadar uzatır if ($isUserActivity) $_SESSION["lastactivity"] = $t; )) ) true değerini döndür; )

    Özetleyelim. Her istekte, son kullanıcı etkinliğinden o anki ana kadar zaman aşımına ulaşılıp ulaşılmadığını kontrol ederiz ve ulaşıldıysa oturumu yok edip işlevin yürütülmesini keserek FALSE döndürüyoruz. Eğer zaman aşımı süresine ulaşılmadıysa ve fonksiyona TRUE değerine sahip $isUserActivity parametresi aktarıldıysa kullanıcının son aktivite zamanını güncelliyoruz. Tek yapmamız gereken, çağıran komut dosyasında isteğin kullanıcı etkinliğinin sonucu olup olmadığını belirlemek ve değilse, $isUserActivity parametresi FALSE olarak ayarlanmış şekilde startSession işlevini çağırmak.

    2013-06-07 tarihinden itibaren güncelleme
    sessionStart() işlevinin sonucunun işlenmesi

    Yorumlarda, FALSE döndürmenin hatanın nedeninin tam olarak anlaşılmasını sağlamadığına ve bunun kesinlikle adil olduğuna dikkat çekildi. Bu, makalenin konusuyla doğrudan ilgili olmadığı için burada ayrıntılı hata işlemeyi yayınlamadım (makalenin uzunluğu zaten oldukça uzun). Ancak yorumlara göre açıklığa kavuşturacağım.

    Gördüğünüz gibi sessionStart işlevi iki durumda FALSE değerini döndürebilir. Ya bazı dahili sunucu hataları (örneğin, php.ini'deki yanlış oturum ayarları) nedeniyle oturum başlatılamadı ya da oturumun süresi dolmuş. İlk durumda, kullanıcıyı sunucuda sorunlar olduğunu belirten bir hata ve destek ile iletişim formu içeren bir sayfaya yönlendirmeliyiz. İkinci durumda, kullanıcıyı giriş formuna aktarmalı ve oturumun süresinin dolduğunu belirten ilgili mesajı burada görüntülemeliyiz. Bunun için FALSE yerine hata kodlarını girip karşılık gelen kodu döndürmemiz ve çağırma yönteminde kontrol edip ona göre hareket etmemiz gerekiyor.

    Artık sunucuda bir oturum hala mevcut olsa bile, kullanıcının hareketsizlik zaman aşımı sona ermişse, ilk kez erişildiğinde bu oturum imha edilecektir. Ve bu, global PHP ayarlarında hangi oturum ömrünün ayarlandığına bakılmaksızın gerçekleşecektir.

    Not: Tarayıcı kapatılırsa ve oturum adı çerezi otomatik olarak yok edilirse ne olur? Tarayıcının bir sonraki açılışında sunucuya gönderilen istek, oturum çerezini içermeyecek ve sunucu, oturumu açıp kullanıcının hareketsizlik zaman aşımını kontrol edemeyecek. Bizim için bu, yeni bir oturum oluşturmaya eşdeğerdir ve işlevselliği veya güvenliği hiçbir şekilde etkilemez. Ancak adil bir soru ortaya çıkıyor: Eğer şimdiye kadar zaman aşımı süresi dolduktan sonra onu yok etmişsek, o zaman eski oturumu kim yok edecek? Yoksa artık sonsuza kadar oturumlar dizininde mi kalacak? PHP'de eski oturumları temizlemek için çöp toplama adı verilen bir mekanizma vardır. Sunucuya bir sonraki istek geldiğinde çalışır ve oturum dosyalarının son değiştirilme tarihine göre tüm eski oturumları temizler. Ancak çöp toplama mekanizması sunucuya yapılan her istekle başlamaz. Başlatma sıklığı (veya daha doğrusu olasılığı), session.gc_probability ve session.gc_divisor adlı iki ayar parametresi tarafından belirlenir. Birinci parametrenin ikinciye bölünmesinin sonucu, çöp toplama mekanizmasını başlatma olasılığıdır. Bu nedenle sunucuya gelen her istekte oturum temizleme mekanizmasının çalıştırılabilmesi için bu parametrelerin eşit değerlere ayarlanması gerekir, örneğin “1”. Bu yaklaşım temiz bir oturum dizinini garanti eder, ancak sunucu için açıkçası çok pahalıdır. Bu nedenle üretim sistemlerinde session.gc_divisor'un varsayılan değeri 1000 olarak ayarlanmıştır, bu da çöp toplama mekanizmasının 1/1000 olasılıkla çalışacağı anlamına gelmektedir. Eğer php.ini dosyanızda bu ayarları denerseniz, yukarıda açıklanan durumda, tarayıcı kapanıp tüm çerezleri temizlediğinde, bir süre daha oturumlar dizininde eski oturumların kaldığını fark edebilirsiniz. Ama bu seni endişelendirmemeli çünkü... Daha önce de belirttiğimiz gibi bu, mekanizmamızın güvenliğini hiçbir şekilde etkilemez.

    2013-06-07 tarihinden itibaren güncelleme

    Oturum dosyasının kilitlenmesi nedeniyle komut dosyalarının donmasını önleme

    Yorumlar, oturum dosyasının engellenmesi nedeniyle aynı anda çalışan komut dosyalarının donması sorununu gündeme getirdi (en dikkat çekici seçenek uzun ankettir).

    Öncelikle bu sorunun doğrudan sunucu yüküne veya kullanıcı sayısına bağlı olmadığını belirtmek isterim. Elbette ne kadar çok istek olursa komut dosyaları o kadar yavaş yürütülür. Ancak bu dolaylı bir bağımlılıktır. Sorun yalnızca bir oturumda, sunucu bir kullanıcı adına birden fazla istek aldığında ortaya çıkar (örneğin, bunlardan biri uzun yoklama, geri kalanı ise normal isteklerdir). Her istek aynı oturum dosyasına erişmeye çalışır ve eğer önceki istek dosyanın kilidini açmadıysa sonraki istek beklemede kalır.

    Oturum dosyası kilitlemesini minimumda tutmak için, oturum değişkenleriyle ilgili tüm eylemler tamamlandıktan hemen sonra session_write_close() işlevini çağırarak oturumu kapatmanız önemle tavsiye edilir. Uygulamada bu, her şeyi oturum değişkenlerinde saklamamanız ve betiğin yürütülmesi sırasında bunlara erişmeniz gerektiği anlamına gelir. Ve bazı çalışma verilerini oturum değişkenlerinde saklamanız gerekiyorsa, oturum başladığında bunları hemen okuyun, daha sonra kullanmak üzere yerel değişkenlere kaydedin ve oturumu kapatın (yani, session_write_close işlevini kullanarak oturumu kapatmak ve session_destroy kullanarak onu yok etmemek anlamına gelir) ).

    Örneğimizde bu, bir oturumu açtıktan hemen sonra, oturum ömrünü ve yetkili bir kullanıcının varlığını kontrol ettikten sonra, uygulamanın gerektirdiği tüm ek oturum değişkenlerini (varsa) okuyup kaydetmemiz, ardından bir çağrı kullanarak oturumu kapatmamız gerektiği anlamına gelir. session_write_close()'a gidin ve ister uzun bir yoklama ister düzenli bir istek olsun, bir betiğin yürütülmesine devam edin.

    Oturumları yetkisiz kullanıma karşı koruma

    Durumu hayal edelim. Kullanıcılarınızdan biri, (oturumumuzun depolandığı) tarayıcı çerezlerini çalan ve bunu belirtilen e-postaya gönderen bir Truva Atı alır. Saldırgan çerezi ele geçirir ve onu yetkili kullanıcımız adına bir isteği taklit etmek için kullanır. Sunucu bu isteği sanki yetkili bir kullanıcıdan gelmiş gibi başarıyla kabul eder ve işler. IP adresinin ek doğrulaması yapılmazsa, böyle bir saldırı, tüm sonuçlarıyla birlikte kullanıcının hesabının başarılı bir şekilde hacklenmesine yol açacaktır.

    Bu neden mümkün oldu? Açıkçası, ad ve oturum tanımlayıcısı oturumun tüm ömrü boyunca her zaman aynı olduğundan ve bu verileri alırsanız, başka bir kullanıcı adına (tabii ki bu oturumun ömrü boyunca) kolayca istek gönderebilirsiniz. Bu en yaygın saldırı türü olmayabilir, ancak teorik olarak oldukça mümkün görünüyor, özellikle de böyle bir Truva Atı'nın kullanıcının tarayıcı çerezlerini çalmak için yönetici haklarına bile ihtiyaç duymadığı göz önüne alındığında.

    Kendinizi bu tür saldırılardan nasıl koruyabilirsiniz? Yine açıkça, oturum tanımlayıcının ömrünü sınırlandırarak ve aynı oturum içinde tanımlayıcıyı periyodik olarak değiştirerek. Eskisini tamamen silip yeni bir oturum oluşturarak, tüm oturum değişkenlerini eski oturuma kopyalayarak da oturumun adını değiştirebiliriz. Ancak bu, yaklaşımın özünü etkilemez; dolayısıyla basitlik adına kendimizi yalnızca oturum tanımlayıcıyla sınırlayacağız.

    Oturum kimliğinin ömrü ne kadar kısa olursa, saldırganın bir kullanıcı isteğini taklit etmek için çerezleri elde etmesi ve kullanması için o kadar az zaman harcayacağı açıktır. İdeal olarak, her istek için yeni bir tanımlayıcı kullanılmalıdır; bu, başka birinin oturumunu kullanma olasılığını en aza indirecektir. Ancak oturum tanımlayıcısının yenilenme süresinin keyfi olarak ayarlandığı genel durumu ele alacağız.

    (Kodun daha önce tartışılan kısmını atlayacağız).

    Function startSession($isUserActivity=true) ( ​​// Oturum tanımlayıcı ömrü $idLifetime = 60; ... if ($idLifetime) ( // Oturum tanımlayıcı ömrü ayarlandıysa, // oturumun sona ermesinden bu yana geçen süreyi kontrol edin oluşturulan veya son yenileme // (oturum değişkeni starttime güncellendiğinde son isteğin zamanı) if (isset($_SESSION["starttime"])) ( if ($t-$_SESSION["starttime"] >= $ idLifetime) ( // Oturum tanımlayıcı ömrünün dolduğu zaman // Yeni bir tanımlayıcı oluşturun session_regenerate_id(true); $_SESSION["starttime"] = $t ) ) else ( // Oturum yeni oluşturulmuşsa buraya geliriz // Oturum tanımlayıcısı oluşturma zamanını geçerli zamana ayarlayın $_SESSION["starttime"] = $t ) ) return true ;

    Bu nedenle, yeni bir oturum oluştururken (kullanıcı başarılı bir şekilde oturum açtığında gerçekleşir), oturum tanımlayıcısının son neslinin zamanını bizim için saklayan oturum değişkeni starttime'ı mevcut sunucu zamanına eşit bir değere ayarlarız. Daha sonra her istekte, tanımlayıcının son neslinden bu yana yeterli sürenin (idLifetime) geçip geçmediğini kontrol ediyoruz ve eğer öyleyse yeni bir tane oluşturuyoruz. Böylece, tanımlayıcının belirlenen ömrü boyunca, yetkili kullanıcının çerezini alan saldırganın bunu kullanacak zamanı yoksa, sahte istek sunucu tarafından yetkisiz olarak kabul edilecek ve saldırgan, giriş sayfasına yönlendirilecektir. .

    Not: Yeni oturum kimliği, session_regenerate_id() işlevi çağrıldığında tarayıcının çerezine girer ve bu, session_start() işlevine benzer şekilde yeni çerezi gönderir, böylece çerezi kendimiz güncellememize gerek kalmaz.

    Oturumlarımızı olabildiğince güvenli hale getirmek istiyorsak, tanımlayıcının ömrünü bire ayarlamak veya hatta session_regenerate_id() işlevini parantezlerden çıkarmak ve tüm kontrolleri kaldırmak yeterlidir; bu, her oturumda tanımlayıcının yeniden oluşturulmasına yol açacaktır. rica etmek. (Bu yaklaşımın performans üzerindeki etkisini test etmedim ve yalnızca session_regenerate_id(true) işlevinin temelde yalnızca 4 eylem gerçekleştirdiğini söyleyebilirim: yeni bir tanımlayıcı oluşturmak, oturum çereziyle bir başlık oluşturmak, eskisini silmek ve oluşturmak yeni bir oturum dosyası).

    Lirik ara söz: Truva atının saldırgana çerez göndermeyecek kadar akıllı olduğu ortaya çıkarsa ve çerezi alır almaz önceden hazırlanmış sahte bir isteğin gönderilmesini organize ederse, yukarıda açıklanan yöntem büyük olasılıkla bu tür bir duruma karşı koruma sağlayamayacaktır. bir saldırıdır, çünkü Truva Atı'nın çerezi alması ile sahte isteğin gönderilmesi arasında neredeyse hiçbir fark olmayacaktır ve bu anda oturum tanımlayıcısının yenilenmeme olasılığı yüksektir.

    Birden fazla kullanıcı adına tek tarayıcıda eşzamanlı çalışma imkanı

    Göz önünde bulundurmak istediğim son görev, birkaç kullanıcının aynı anda tek bir tarayıcıda çalışabilmesidir. Bu özellik, kullanıcıların eşzamanlı çalışmasını taklit etmeniz gerektiğinde özellikle test aşamasında kullanışlıdır ve mevcut cephaneliğin tamamını kullanmak veya tarayıcının birkaç örneğini gizli modda açmak yerine bunu favori tarayıcınızda yapmanız önerilir. .

    Önceki örneklerimizde açıkça bir oturum adı belirtmedik, dolayısıyla varsayılan PHP adı (PHPSESSID) kullanıldı. Bu şu ana kadar oluşturduğumuz tüm oturumların tarayıcıya PHPSESSID adı altında bir çerez gönderdiği anlamına gelir. Açıkçası, çerez adı her zaman aynıysa, aynı tarayıcıda aynı adla iki oturum düzenlemenin bir yolu yoktur. Ancak her kullanıcı için kendi oturum adımızı kullansaydık sorun çözülürdü. Hadi yapalım.

    Function startSession($isUserActivity=true, $prefix=null) ( ... if (session_id()) return true; // Kullanıcı öneki parametrelerde iletilirse, // bunu içeren benzersiz bir oturum adı ayarlayın önek, // aksi halde tüm kullanıcılar için ortak ad belirleyin (örneğin, PROJEMİM) session_name("PROJEM".($prefix ? "_".$prefix: "") ini_set("session.cookie_lifetime", 0); if (! session_start()) false değerini döndürürse;

    Artık geriye kalan tek şey, çağıran betiğin her kullanıcı için startSession() işlevine benzersiz bir önek iletmesini sağlamaktır. Bu, örneğin her isteğin GET/POST parametrelerine bir önek ileterek veya ek bir çerez aracılığıyla yapılabilir.

    Çözüm

    Sonuç olarak, yukarıda tartışılan tüm görevleri de içeren, PHP oturumlarıyla çalışmaya yönelik işlevlerimizin tam son kodunu sunacağım.

    Function startSession($isUserActivity=true, $prefix=null) ( $sessionLifetime = 300; $idLifetime = 60; if (session_id()) return true; session_name("PROJEM".($prefix ? "_".$prefix: "")); ini_set("session.cookie_lifetime", 0); if (! session_start()) return false; $t = time(); if ($sessionLifetime) ( if ($_SESSION["lastactivity"] ) $t-$_SESSION["lastactivity"] >= $sessionLifetime) ( destroySession(); return false; ) else ( if ($isUserActivity) $_SESSION["lastactivity"] = $t; )) if ($idLifetime ) ( if (isset($_SESSION["başlangıçzamanı"])) ( if ($t-$_SESSION["başlangıçzamanı"] >= $idLifetime) ( session_regenerate_id(true); $_SESSION["başlangıçzamanı"] = $t; ) ) else ( $_SESSION["starttime"] = $t; ) ) return true; function destroySession() ( if (session_id()) ( session_unset(); setcookie(session_name(), session_id(), time() -60* 60*24); oturum_destroy();

    Bu makalenin oturum mekanizmasını daha önce çok derinlemesine incelememiş olanlar için biraz zaman kazandıracağını ve PHP ile yeni tanışmaya başlayanlar için bu mekanizma hakkında yeterince bilgi vereceğini umuyorum.

    HTTP durum bilgisi olmayan bir protokoldür. Bu, kullanıcının bir istek gönderdiği, sunucunun bu isteğe daha sonra isteği hatırlamadan yanıt verdiği anlamına gelir. Önemli bilgileri (örneğin, kullanıcı tercihleri, kullanıcı eylemleri vb.) izlemek için web sitesinde PHP kullanılarak çerezler oluşturulur. Bu yazımda çerezlerle nasıl çalışılacağından, nasıl oluşturulması gerektiğinden, hangi parametrelere sahip olduğundan ve bunları nasıl silebileceğinizden bahsedeceğim.

    Çerez Nedir?

    Çerezler, bilgilerin doğrudan kullanıcının tarayıcısında saklanması açısından çok faydalıdır. Bu, maksimum 4kb veri depolayan basit bir metin dosyasıdır.

    Çerezler, sunucunun isteği üzerine (program mantığına uygun olarak) tarayıcı tarafından oluşturulur. Kullanıcı tarafında bir çerez oluşturulduktan sonra, kullanıcının tarayıcısı bu bilgiyi (çerezden) bir HTTP başlığı kullanarak sunucuya geri gönderir.

    Oturum açma bilgileri, şifreler vb. genellikle çerezlerde saklanır. Örneğin siteye giriyorsunuz, kullanıcı adınızı ve şifrenizi giriyorsunuz. Site bu verilerle sizin için otomatik olarak çerezler oluşturur. Ve siteyi bir sonraki ziyaretinizde, çerezlerin varlığını kontrol eder ve bunlara kaydedilen kullanıcı verilerini yükler.

    //Böyle bir site için indeks sayfası örneği if($_COOKIE["login"])(header("location: /lk/index.php?login=".$_COOKIE["login"]);// Doğrudan kişisel hesabınıza aktarılacaktır ) //Sonraki örneğin giriş ve kayıt formudur

    Neden Çerez?

    HTTP durum bilgisi olmayan bir protokoldür, dolayısıyla kullanıcının bir sitedeki önceki eylemlerini takip etmenin bir yolu yoktur. Çerezler veri depolamanın en iyi yoludur. Ben kırdığınız dilek kurabiyeleri hakkında her şeyi biliyorum ve içinde gelecekte başınıza neler gelebileceğine dair bir kağıt parçası var. isim.

    PHP Çerezleri

    Aslında ne olduğunu daha önce açıkladığıma göre, PHP'de çerezlerin nasıl ayarlandığını öğrenelim.

    Kullanıcının tarayıcısında çerezleri ayarlamak için SetCookie() yöntemini kullanırız.

    PHP'de çerezleri ayarlamak için sözdizimi

    Setcookie(isim, değer, zaman, yol, etki alanı, güvenli);

    name - Çerezin adını belirtir.

    val - Çerezde saklamak istediğimiz değer. Bir çerez her zaman bir dize değeri saklar.

    süre (isteğe bağlı) - Çerez son kullanma süresini ayarlayın. Bu alan boş ise tarayıcı kapatıldığında çerezler silinecektir.

    etki alanı (isteğe bağlı alan) - Çerezin mevcut olduğu etki alanını ayarlayın. Birden fazla alt alan adı için bir çerez ayarlamak istiyorsanız ana alan adını, önek olarak bir noktayla birlikte kullanın.

    Örneğin:

    My.com'un tech.my.com, only.my.com gibi birkaç alt alan adı olmasına izin verin. Ve my.com'daki çerez setinin tüm alt alan adlarımda kullanılabilir olmasını istiyorum, ardından alan adını.my.com olarak ayarlıyorum.

    güvenli(isteğe bağlı) - Bu, çerezin HTTPS kullanılarak güvenli bir bağlantı üzerinden gönderilip gönderilmeyeceğini belirler. Varsayılan YANLIŞ olarak ayarlanmıştır. Bu doğru olarak ayarlanırsa, bu, çerezin yalnızca güvenli bir bağlantı mevcutsa kurulacağı ve HTTP ile oluşturulmamasının mantıklı olduğu anlamına gelir.

    Setcookie("giriş", "valera123");

    Yukarıdaki betiği kullanarak, giriş adında ve valera123 değerinde bir çerez oluşturacağız.

    Not: Çerezler yalnızca dize değerlerini saklayabilir. Bir diziyi depolayamazlar. Bir diziyi çerezlerde saklamak için önce onları bir dizeye dönüştürmeniz gerekir. Bunu size daha sonra mutlaka anlatacağım.

    Not: Fark ettiğiniz gibi çerezimizin ömrünü ayarlamadım. Bu nedenle tarayıcımız kapatıldıktan sonra kaybolacaktır...

    SetCookie() yöntemini kullanarak çerezimiz ayarlanacaktır. Komut dosyanız belirtilen yöntemle yürütüldükten sonra, çerezi Chrome'daki geliştirici panelinden veya Firefox'taki firebug'dan kolayca kontrol edebilirsiniz.


    Çerez son kullanma süresini tanımlamadık. Ona 30 gün verelim. Bu durumda zamandan bahsetmemiz gerekir. Bundan sonra kullanıcı manuel olarak silene kadar 30 gün boyunca geçerli olacaktır.

    Setcookie("giriş", "valera123",zaman()+3600*24*30);

    3600 - 1 saat
    24 gün
    30 gün

    Alt alan adları için çerezler nasıl ayarlanır?

    setcookie("giriş", "valera123",time()+3600*24*30,"/",.my.com");

    Aslında bu örnek daha önce verilmişti

    PHP'de çerez değeri nasıl elde edilir

    $_COOKIE - bir çerezin değerini almak için kullanılır. Daha önce yüklenen çerezin değerini tam olarak nasıl alabileceğinizi gösteren kod aşağıdadır.

    $val = $_COOKIE["giriş"]; echo $val; //valera123 çıktısı

    PHP'de Çerez nasıl kaldırılır

    PHP'de çerezleri kaldırmak için zamanı olumsuz (geçmiş zaman) olarak ayarlayın.

    Setcookie("giriş", "valera123",time()-3600*24);

    Peki zamanı negatife ayarlarsak ne olur? Bu durumda çerezin süresi otomatik olarak sona erer.

    Çerezler hakkında önemli noktalar

    1. Bir çerez maksimum 4 KB veri saklayabilir.

    2. Yalnızca dizeleri saklayabilir.

    3. Çerezlere yalnızca onları ayarlayan tarayıcı tarafından erişilebilir. Chrome tarayıcısına yüklenen çerezlere Mozilla tarayıcısından veya başka bir tarayıcıdan erişilemez.

    4. Gizli ve son derece hassas verilerin çerezlerde saklanmasından kaçının.

    Aslında hepsi bu. Umarım bu satırı beğenmişsinizdir, görüşlerinizi yorumlarda paylaşın ve yeniden yayınlamayı unutmayın.

    Peki, hadi çözelim.

    İlk olarak aynı wiki'de HTTP hakkında bilgi edinin. Tamamen bilmenize gerek yok, ancak istek/yanıt yapısını asgari düzeyde anlamış olmanız, istek ve yanıtın başlıklara ve bir gövdeye sahip olduğunu anlamalısınız (istek/yanıt türüne bağlı olarak bir gövde olmayabilir) cevap).

    İşte burada. Kurabiye. Çerezler tarayıcı tarafında bulunur. Sunucuya yapılan her istekte HTTP başlığında iletilir (resimleri almaya gitseniz bile). Yalnızca çerezler var, yalnızca http çerezleri var. Çerezler ana makineye ve yola göre ayrılabilir. Bütün bunlar bize esneklik kazandırıyor ve güvenliğe yardımcı oluyor. PHP'de $_COOKIE içeriği bize SAPI tarafından sağlanmaktadır. PHP işleme için bir istek aldığında, kullanılan SAPI (php-fpm, cgi, mod_php'nin kendi SAPI uygulamaları vardır) şu anda isteğin başlıklarını ve gövdesini alır, bunları ayrıştırır ve $_SERVER, $_GET gibi tüm bu süper küresel dizileri doldurur. vb. $_COOKIE. Müşterinin bize gönderdiği her şey (istekleri yapan şey istemcidir, bunları işleyen şey ise sunucudur) ve tarayıcı bize yalnızca isteğin gönderildiği yere bağlı olarak mümkün olan çerezleri gönderir. Çerezler yanıttaki Set-Cookie başlığı kullanılarak ayarlanır, yani burada PHP hakkında değil HTTP hakkında daha fazla bilgi okumanız gerekir. PHP sadece bu şeylerle çalışmanıza izin verir. Başlık işlevini kullanarak yanıt başlıklarıyla çalışarak çerezleri doğrudan ayarlayabilirsiniz. Ayrıca, çerezlerin ömrünü 0'a ayarlarsanız, tarayıcı kapatıldığında oturum değil, çerezler sıfırlanacak, çünkü tüm bu çerezler unutulacaktır.

    Burada... oturumlar... PHP'de oturum genellikle bir dosyadır. Sadece rastgele bir isme sahip bir dosya. Örneğin, php.ini dosyasında session.autostart belirtilirse veya bir session_start çağrısı yapılırsa, kullanıcı oturumu için bir dosya oluşturulur (ihtiyaçlarınıza bağlı olarak bunu Radish'e veya Memcache'e, depolama alanınıza vb. taşıyabilirsiniz). Veriler aynı zamanda şifrelenebilir, bu da varsayılan olarak gerçekleşir). Bu dosyanın bir kimliği var, sadece rastgele bir dize. Ve eğer bir istek işlenirken önceki isteğe ait bir oturum bulunamazsa, yeni bir istek oluşturulur.

    Ve şimdi en ilginç şeye geliyoruz - PHP'nin önceki istekteki oturumu mevcut istekle nasıl bağladığı. Ve burada her şey oldukça basit - kurabiyeler. Bir kullanıcıya bir oturum atandığında, oturum tanımlayıcının yazıldığı yalnızca http çerezi otomatik olarak ayarlanır (böylece kötü kişiler oturumumuzu js'den çalamaz). Tarayıcı hata ayıklayıcısında, oturumları denediğinizde PHPSESSID çerezinizin olup olmadığını (adı ayarlardan değiştirilebilir ve genel olarak oturumlar yalnızca çerezler aracılığıyla bağlanamaz, bunlar zaten güvenlik sorunlarıdır) olup olmadığını görebilirsiniz.

    Bir istek SAPI tarafından işlendiğinde, eğer session.autostart varsa, yeni bir oturum oluşturmaya başlamadan önce, puf yine de oturum tanımlayıcıya sahip bir çerezimiz olup olmadığına bakar, olup olmadığını kontrol eder ve varsa, sakinleşir ve yenisini yaratmaz. Oturum çerezler aracılığıyla bağlı olduğundan, bu çerezin ömrünü (php.ini'de) kendiniz ayarlayabilir ve böylece oturumun ömrünü düzenleyebilirsiniz.

    İşte... çerezler ne zaman kullanılmalı ve oturumlar ne zaman kullanılmalı? Çerezlerde ne kadar fazla veri varsa (ve bunların bir kelime sınırı varsa), her istek için o kadar fazla veri aktardığımızın anlaşılması tavsiye edilir. Yani, 1 kilobaytlık veri almak için başlıklara birkaç kilobaytlık çerez aktarmamız hiç hoş değil. Optimizasyona odaklanan kişiler, trafik ve paket miktarını azaltmak için görüntüleri ayrı çerez içermeyen alanlarda bile saklarlar (genellikle basit bir HTTP isteği, bir TCP paketinin boyutuna sığar). Herhangi bir sayfada JS'den gelen bu verilerle (örneğin, JS'de çevirileri uygulamak için kullanıcı tarafından seçilen yerel ayar) çalışmanız gerekiyorsa, çerezleri kullanmalısınız. Diğer her şey için elbette oturumları kullanmak daha iyidir. Her durumda, çok karmaşık bir şey yapmanıza gerek olmadığı ilk aşamalarda.