Menü
Bedava
giriş
ana  /  internet / Oturum, toplantı, celse. Oturum kontrolü, uygulama şifreleri ve Facebook oturum açma onayı Aktif oturum

Oturum, toplantı, celse. Oturum kontrolü, uygulama şifreleri ve Facebook oturum açma onayı Aktif oturum

Web sunucusu, istemciye kalıcı bir bağlantı sağlamaz ve her istek, öncekilerle herhangi bir bağlantı olmaksızın yeni bir istek gibi ele alınır.
Yani, ne aynı ziyaretçiden gelen istekleri takip edemezsiniz ne de onun için görünümler arasında değişkenler kaydedemezsiniz. bireysel sayfalar... Bu iki sorunu çözmek için oturumlar icat edildi.
Aslında, kısaca oturumlar, bir tarayıcıyı benzersiz şekilde tanımlamanıza ve sunucuda bu tarayıcı için oturum değişkenlerini depolayan 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ğazada alışveriş sepeti, yetkilendirme gibi ders kitabı vakaları ve ayrıca, örneğin, sitenin etkileşimli bölümlerini spam'den korumak gibi tamamen önemsiz sorunlar değil.

Prensipte, kendi oturum analoğunuzu yerleşik PHP kadar işlevsel değil, özünde benzer şekilde yapmak oldukça kolaydır. Çerezler ve veri tabanında.
Bir komut dosyası talep ederken, bir çerezin belirli bir adla gelip gelmediğini görürüz. Tanımlama bilgisi yoksa, onu ayarlayın ve veritabanına kullanıcı verilerini içeren yeni bir satır yazın. Bir çerez varsa, veritabanından okuruz. Başka bir istek ile eski kayıtları veritabanından siliyoruz ve artık hazır bir oturum mekanizmamız var. Hiç zor değil. Ancak yerleşik oturum mekanizmasının kullanılmasını tercih edilir kılan bazı nüanslar vardır.

Yalnızca ilki etkinleştirilirse, oturumun başlangıcında (her aramada session_start ()) müşteri için bir çerez kurulur. Tarayıcı, sonraki her istekte bu çerezi doğru bir şekilde döndürür ve PHP'nin bir oturum tanımlayıcısı vardır. Tarayıcı tanımlama bilgilerini döndürmezse sorunlar başlar. Bu durumda, PHP bir tanımlayıcıya sahip çerezleri almadan her zaman yeni bir oturum başlatır ve mekanizma çalışmaz.

Yalnızca ikincisi etkinleştirilirse, çerez ayarlanmamıştır. Ve olan şey şu ki, temelde aslında yerleşik oturum mekanizmasını kullanmaya değer. Betik işini yaptıktan ve sayfa tam olarak oluşturulduktan sonra, PHP hepsine bakar ve oturum kimliğini her bağlantıya ve her forma ekler. Şuna benzer:
Dizin dönüşür
Dizin
ve formlara gizli bir alan eklendi

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

Teorik olarak, sizinle çerezler ve temel üzerinde ev yapımı oturumlarımızda, kimlik aktarımını tüm bağlantılara manuel olarak atayabilirsiniz - ve daha sonra kendi oturumlarımız çerezlerden bağımsız olarak çalışacaktır. Ama görüyorsunuz - başka biri bu işe yaradığında daha hoş? ;-)

Varsayılan olarak son sürümler PHP her iki seçeneği de içerir. PHP bunu nasıl halleder? Cook her zaman sergilenir. Ve bağlantılar yalnızca PHP oturum kimliğine sahip bir çerez bulamazsa otomatik olarak tamamlanır. Bir kullanıcı bu oturum sırasında siteyi ilk kez ziyaret ettiğinde, ona bir çerez yerleştirilir ve bağlantılar tamamlanır. Bir sonraki istekte, çerezler destekleniyorsa, PHP çerezi görür ve bağlantı eklemeyi durdurur. Çerezler çalışmazsa, PHP bağlantılara düzgün şekilde id eklemeye devam eder ve oturum kaybolmaz.
Çerezleri çalışan kullanıcılar, kimliğe sahip uzun bağlantıyı yalnızca bir kez göreceklerdir.

Fuh. Tanımlayıcının aktarımı bitti.
Şimdi, sunucu tarafındaki verileri içeren bir dosyayı kendisine bağlamak için kalır.
PHP bunu bizim için yapacak. Sadece yazmak yeterli
session_start ();
$ _SESSION ["test"] \u003d "Merhaba dünya!" ;

Ve PHP, test değişkenini bu oturumla ilişkili dosyaya yazar.
Burada çok önemli bir nokta var.
Dizi $ _SESSION - özel.
Aslında içinde, çeşitli betiklerde kullanılabilir hale getirmek istediğimiz değişkenler var.
Bir oturuma bir değişken yerleştirmek için, onu $ _SESSION dizisinin bir öğesine atamanız yeterlidir.
Değerini elde etmek için aynı öğeye başvurmanız yeterlidir. Aşağıda bir örnek verilecektir.

Çöp toplama - eski olanı kaldırma pHP dosyaları kendim de yapıyor. Veri kodlamanın yanı sıra diğer gerekli şeyler. Bu bakımın bir sonucu olarak seanslarla çalışmak oldukça kolaydır.
Burada aslında seans çalışmalarının örneğine geliyoruz.
Örnek çok küçük:
session_start ();

eko "Bu sayfayı güncellediniz"... $ _SESSION ["sayaç"] ++. "zamanlar.";
eko "
güncelleme ";
?>

Oturumda bir sayaç değişkenimiz olup olmadığını kontrol ederiz, yoksa onu 0 değeriyle oluştururuz ve ardından değerini çıkarır ve bir artar. Artan değer oturuma yazılacak ve komut dosyası bir sonraki çağrıldığı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 ihtiyacımız olan HER dosyanın en başında SADECE BİR (!) Satır yazmanız gerekir:
session_start ();
Ve sonra $ _SESSION dizisinin öğelerine bakın. Örneğin, bir yetkilendirme kontrolü şuna benzer:
session_start ();
eğer ($ _SESSION ["yetkili"]<> 1 ) {
başlık ("Konum: /auth.php");
çıkış;
}

Bir oturumdan değişkenleri kaldırmak.
Register_globals \u003d off'a sahipseniz, sadece yazın
ayarlanmadı ($ _ SESSION ["var"]);
O zaman değilse yakınlarda Onunla yazmam lazım
session_unregister ("var");

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

aynı sebepten kaynaklanırsa, çözüm bu gerçekte anlatılır
Üçüncü,
Uyarı: open (/ tmp \\ sess_SID, O_RDWR) başarısız oldu: Satır numarasındaki full_script_path içinde böyle bir dosya veya dizin (2) yok (önceden benziyordu Uyarı: Oturum verileri (dosyalar) yazılamadı. Lütfen geçerli session.save_path ayarının doğru olduğunu doğrulayın (/ tmp)),
İngilizceden çevrilmişse, sorunu ayrıntılı olarak açıklar: php.ini'de belirtilen, oturum dosyalarının yazıldığı dizine giden yol mevcut değildir. Bu hata, düzeltilmesi en kolay olanıdır. Sadece var olan ve yazılabilir bir dizin yazın, örneğin,
session.save_path \u003d c: \\ windows \\ temp
Ve bundan sonra Apache'yi yeniden başlatmayı unutmayın.

Görünüşe göre, insan zekasının sınırı yok ve bu yüzden açıklamam gerekiyor:
üçüncü hata mesajı (dizin bulunamıyor) kaçınılmaz olarak ilk ikisine yol açacaktır, çünkü hata mesajı tarayıcıya gönderilir ve bundan sonra başlıkları kullanamazsınız. Bu nedenle, erken bir sonuç aramak için acele etmeyin, önce doğru yolu yazın!

Oturumlarla ilgili bir sonraki en yaygın sorun, ağır register_globals mirasıdır. Komut dosyası değişkenlerine $ _SESSION dizisinin indisleri ile aynı isimleri VERMEYİN!
Register_globals \u003d on ile değerler birbirinin üzerine yazılır ve kafanız karışır.
Ve register_globals \u003d off ise, başka bir hata ortaya çıkacaktır: "Betiğiniz muhtemelen PHP 4.2.3'e kadar var olan bir oturum yan etkisine dayanmaktadır.", Komut dosyasında değeri olmayan bir oturum değişkeni ve bir genel aynı isimli değişken ... Ondan kurtulmak için, kullanmadan önce değişkenleri her zaman başlatmalısınız (veya en azından var olup olmadığını kontrol etmelisiniz) ve $ _SESSION dizisinin indisleriyle eşleşen global değişken isimleri vermemelisiniz.

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

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

Hata olmadığından eminseniz, ancak verilen örnek yine de çalışmıyorsa, PHP'nin url aracılığıyla id transferini etkinleştirmemesi mümkündür, ve çerezler herhangi bir nedenle çalışmıyor.
Çerezlerle ne olduğunu görün.
Genel olarak, oturumlarınız "çalışmıyorsa", o zaman önce oturum tanımlayıcısını elle aktarmayı deneyin, yani bir bağlantı oluşturun ve ona bir tanımlayıcı atayın:
session_start ();
eğer (! isset ($ _ SESSION ["sayaç"])) $ _SESSION ["sayaç"] \u003d 0;
eko "Bu sayfayı güncellediniz"... $ _SESSION ["sayaç"] ++. "zamanlar.

güncelleme ";
?>

Bunu yaparken, PHP'nin bir URL'den geçirilmişse bir oturum kimliğini kabul etmesini engelleyen session.use_only_cookies yönergesinin etkin olmadığından emin olun.

Bu örnek işe yaramazsa, sorun ya banaldir. yazım hataları (oturumlarla ilgili "sorunların" yarısı yanlış yazılmış bir değişken adından gelir) veya eski versiyon PHP: oturum desteği 4.0 sürümünde tanıtıldı ve dizi $ _SESSION - 4.1'de (Önceden kullanılmış $ HTTP_SESSION_VARS).
Çalışırsa, sorun tanımlama bilgilerindedir. Tarayıcının iade edip etmediğini, sunucunun tarayıcıya ne tür çerez koyduğunu izleyin. Tarayıcı ve sunucu arasındaki HTTP başlık değişimlerine bakarken arama yapmak çok kullanışlıdır.
Tanımlama bilgilerinin nasıl çalıştığını açıklamak, zaten çok büyük olan bu metnin kapsamı dışındadır, ancak en azından sunucunun tanımlama bilgisini tanımlayıcıyla göndermesini ve tarayıcının geri dönmesini sağlayın. Ve tanımlayıcılar birbirleriyle çakışırken \u003d)
Çerezi ayarlamak şöyle görünmelidir
Set-Çerez: PHPSESSID \u003d prlgdfbvlg5fbsbshch6hj0cq6;
veya nasıl
Set-Çerez: PHPSESSID \u003d prlgdfbvlg5fbsbshch6hj0cq6; yol \u003d /
(kök dizinden olmayan bir komut dosyası talep ediyorsanız)
Sunucu yanıtı şöyle görünmelidir
Çerez: PHPSESSID \u003d prlgdfbvlg5fbsbshch6hj0cq6
veya
Çerez: PHPSESSID \u003d prlgdfbvlg5fbsbshch6hj0cq6; b \u003d b
tarayıcı, oturum kimliğinin yanı sıra başka çerezler döndürürse

Tarayıcı çerezleri döndürmezse, çerezlerin çalışıp çalışmadığını kontrol edin.
Erişmekte olduğunuz etki alanının normal bir adı olduğundan (en az bir nokta içeren ve alt çizgi gibi yasak 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 işe yarıyorsa, ancak kendi kodunuz çalışmıyorsa, o zaman sorun açıkça oturumlarda değil, algoritmada demektir. Değişkeni nerede kaybettiğinizi arayın, buradan örneği adım adım aktarın, betiğinizin hatalarını ayıklayın.

Başlık yeniden yönlendirmesi veya JavaScript gezinmesi kullanırsanız başka bir sorun ortaya çıkabilir.
Gerçek şu ki, PHP oturum tanımlayıcısını otomatik olarak yalnızca formun bağlantılarına ekler. ancak bunu başlıklar, javascript, meta etiketler için yapmaz.
Bu nedenle, örneğin şu şekilde tanımlayıcıyı elle eklemeniz gerekir:
başlık ("Konum: /script.php?". session_name (). "\u003d". session_id ());

Ayrıca, çok nadirdir ve sorunun nereden geldiği tamamen belirsizdir, session.save_handler ayarının files dışında bir değere sahip olduğu görülür. Değilse düzeltin.

Güvenlik
Oturum güvenliği geniş bir konudur. Bu nedenle birkaç ana noktaya odaklanacağım.
Çoğu ders kitabı, tanımlayıcıyı adres çubuğu... 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 \u003d 0 dışında, session.use_only_cookies \u003d 1'i 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 yine de kullanamayacaktır.
Oturum dosyalarını kaydetmek için kendi dizininizi ayarlamak için kullanabileceğiniz session.save_path yönergesini kullanmanız önerilir. Bu, sunucunun varsayılan paylaşılan geçici dizininde depolandıklarından daha güvenlidir.

Ek bilgi:

  • Çerezlere ek olarak, oturum mekanizması ayrıca sayfa önbelleğe almayı yasaklayan başlıklar da gönderir (aynı önbellek sınırlayıcı). Html için bu doğru ve gereklidir. Ancak, yetkilendirmeyi kontrol eden bir komut dosyası içeren bir dosya göndermeye çalıştığınızda, Internet Explorer onu indirmeyi reddeder. Bu başlık yüzünden. Telefon etmek
    session_cache_limiter ("özel");
    oturuma başlamadan önce sorunu çözmelidir.
  • İşin garibi, ama dizide $ _SESSION sayısal endeksler kullanamazsınız - $ _SESSION [1], $ _SESSION ["10"] - seanslar işe yaramayacak.
  • 4.2 ile 5.0 arasında bir yerde session.use_trans_sid ile ayarlamak mümkün değildi ini_set () ... 5.0'dan başlayarak yine mümkün.
  • 4.3.3 sürümünden önce php tanımlama bilgisi yalnızca oturumun başında istekte tanımlayıcı yoksa bir tanımlama bilgisi gönderir. Artık çerez her aramada gönderiliyor session_start ()

    Oturumları kullanarak yetkilendirme örneği
    Yukarıdakilerin hepsini küçük bir örnekle açıklayalım:
    auth.php dosyası oluşturalım:
    eğer (ayarlanmış ($ _ POST ["kimlik_adı"]))
    {
    $ sql \u003d "SEÇİN * kullanıcılardan NEREDE isim \u003d? S";
    $ satır \u003d $ db -\u003e getRow ($ sql, $ _POST ["kimlik_adı"]);
    eğer ($ row && password_verify ($ _POST ["auth_pass"], $ satır ["pass"])) (
    $ _SESSION ["user_id"] \u003d $ satır ["id"];
    }
    başlık ("Konum: http: //". $ _SERVER ["HTTP_HOST"]. $ _SERVER ["REQUEST_URI"]);
    çıkış;
    }

    if (isset ($ _ GET ["eylem"]) VE $ _GET ["eylem"] \u003d\u003d "çıkış") (
    session_start ();
    session_destroy ();
    başlık ("Konum: http: //". $ _SERVER ["HTTP_HOST"]. "/");
    çıkış;
    }

    eğer (! isset ($ _ SESSION ["kullanıcı_kimliği"])) (
    ?>








    çıkış;
    }

    Artık tüm korumalı komut dosyalarına satır yazmak yeterli
    "auth.php" gerektirir;
    Bu örnek, oturumun zaten başladığını ve veritabanına bağlantının MySQL ile güvenli ve rahat çalışma için Class kullanılarak oluşturulduğunu varsayar. Ayrıca, parolanın önerilen password_hash işlevi kullanılarak karma hale getirildiğini varsayar.
    Korumalı bir dosya örneği:

    session_start ();
    "safemysql.class.php" dahil;
    $ db \u003d yeni safemysql (["db" \u003d\u003e "test"]);
    "auth.php" içerir;
    ?>
    gizli

    çıkış Yap

    OPS! Çok Faydalı Linkler:
    http://www.php.net/manual/ru/ref.session.php - resmi belgelerde PHP oturumları desteğiyle ilgili en son ve güncel bilgiler ve ayrıca çok sayıda kullanıcı yorumu. Okumak şiddetle tavsiye edilir.
    http://phpclub.ru/manrus/f/ref.session.html - Bu bölümün Alexander Pyramidin tarafından çevrilen belgelerden Rusçaya ÇOK güncel olmayan çevirisi.
    http://phpclub.ru/detail/article/sessions
    İddialı "Oturumlar Hakkındaki Gerçek" başlıklı bir makale. Kararsız bir izlenim bırakıyor. Başlangıçta yazar oturum mekanizmasından ÇOK kolay bahsediyor, ancak makalenin sonuna doğru önerdiği yöntemler tamamen çamurlu.

    Siteden Dmitry Borodin'in ders kitabı makalesi
    http://php.spb.ru/ kesinlikle ÖNERİLMEZ.
    Beyler, çok güncel değil. Yalnızca gerçek hatalar değil, PHP'deki oturumlar uzun süredir çalışmıyor.
    Dima'ya onun için çok teşekkürler, bu Rusça oturumlarla ilgili ilk makaleydi, kendim çalıştım, ama şimdi onu hak ettiği bir dinlenmeye göndermem gerekiyor.
    Ayrıca maalesef internette bulunan ve yıllardır güncellenmemiş diğer birçok makale güncelliğini yitirmiştir.

  • Oturum gibi bir şeye bakalım (HTTP oturumu, Oturum). Veya başka bir deyişle, bir kullanıcı oturumu. Seansların nasıl çalıştığını anlamak neden önemlidir? Ve ASP.NET'te oturum durumlarıyla nasıl çalışabileceğinizi görelim.

    "Oturum" teriminin tanımını vermeden önce, arka plana biraz bakalım, neden oturumlara ihtiyaç vardı, HTTP protokolünün bir özelliğini ele alalım.

    HTTP protokolünün temel özelliklerinden biri, sunucuyu istemcilerle ilgili bilgileri istekler arasında saklamaya, yani istemciyi tanımlamaya zorlamamasıdır. Bu sözde vatansız protokoldür. İstemci ile sunucu arasındaki iletişim, mevcut talebin işlenmesi tamamlanır tamamlanmaz sona erer. Sunucuya yapılan her yeni isteğin, aynı kaynaktan yeniden gönderilmiş olsa bile, tamamen benzersiz ve bağımsız olduğu varsayılır.

    HTTP protokolünün durumsuz doğasını bırakırsak ve kullanıcının kimliğini doğrulamazsak ne olur? Siteniz, metin ve resimlerden oluşan bir haber makalesi gibi statik (anonim) bilgiler içeriyorsa, oturum durumlarından kolayca vazgeçilebilir. Böyle bir bağlamda, birden fazla isteği aynı kullanıcıyla ilişkilendirmek tamamen gereksizdir. Sonuçta, ister bir cihazdan on isterse farklı kişilerden farklı cihazlardan on isterse, makalenin içeriği hiçbir şekilde değişmeyecektir.

    Ancak kişisel bilgileri sunucuya aktaracağımız anda, sunucunun tüm isteklerimizi bizimle ilişkilendirdiğinden ve gelecekte bizden giden tüm istekleri doğru şekilde tanımladığından emin olmalıyız. Bu yapılmazsa, her yeni talepte gerekli kişisel verileri yeniden iletmek zorunda kalacağız. Örneğin, girmek için oturum açın kişisel Alan çevrimiçi bir mağazadan satın alırken sitede veya ad, gönderim adresi gibi bilgiler.

    Bu tür durumlarda, bir müşteriden gelen istekleri kişiselleştirmemiz gerektiğinde, oturumları kullanacağız.

    Oturum, toplantı, celse (oturum, toplantı, celse) bir web uygulamasının bir istemciden gelen tüm istekleri belirleyebildiği belirli bir süredir.

    Bir müşteri bir talepte kişisel verileri ilk kez ilettiğinde, o müşteri için sunucuda yeni bir oturum oluşturulur. Oturumun ömrü boyunca, bu istemciden gelen tüm istekler benzersiz bir şekilde tanınacak ve onunla ilişkilendirilecektir. Bu süreden sonra, müşteri ile iletişim kesilecek ve ondan gelen bir sonraki talep, öncekilerle ilgili olmayan, kesinlikle benzersiz olarak işlenecektir.

    Örneğin, bir çevrimiçi mağazada alışveriş yaparken, kullanıcının kişisel bilgileri sitede gezinirken oturuma kaydedilir. Bunlar alışveriş sepetindeki seçili öğeler, teslimat adresi, iletişim bilgileri vb.

    Şimdi bunu teknik olarak nasıl uygulayabileceğimize bakalım. Genel olarak, istemci oturumlarını yönetmek için çeşitli teknikler vardır, bunların sayısı ve uygulama yöntemi büyük ölçüde sunucuda çalışan web platformuna veya teknolojiye bağlıdır. Bu eğitimde aşağıdakileri ele alacağız:

    1. gizli form alanları
    2. kurabiye
    3. oturum (oturum, oturum Durumu)

    Bunları ASP.NET platformunu kullanarak uygulamaya çalışalım. İlk iki mekanizmaya hızlıca bir göz atalım ve daha güvenilir, kullanışlı ve güvenli olan üçüncü mekanizmaya özellikle dikkat edelim.

    Gizli form alanları

    Bu yaklaşımın özü, standart html formlarını kullanarak site navigasyonu sağlamamızdır. Ve sonraki her talepte, bir öncekinden alınan verileri formdaki gizli alanlara kaydediyoruz. Örneğin:

    @using (Html.BeginForm ("Forms2", "Home", FormMethod.Post)) (

    Yemek sipariş etmek

    }

    Genel ActionResult Forms2 () (ViewBag.UserName \u003d Request.Form ["userName"]; return View ();)

    @using (Html.BeginForm ("Forms3", "Home", FormMethod.Post)) (

    @ ($ "İyi günler (ViewBag.UserName)! Ne sipariş edeceksiniz?")

    }

    Bu örnekte, kullanıcı adını ilk html formunda alıyoruz. Yöntemdeki kontrolörde ayrıca Formlar2 () bu değeri koleksiyondan alıyoruz Form ve nesnenin içinden görünüme geçirin ViewBag... Bu görünüm kod üretir yeni form ve gizli alan kullanıcı adını saklar. Böylece, kullanıcı adı değeri ile birlikte üçüncü forma aktarılacaktır. ek bilgi - isimli alanın değeri "foodName"... Vb.

    Gelin bu yaklaşımın özelliklerine bir göz atalım. Bu tekniğin çok hızlı bir şekilde uygulanabilmesi dışında pratikte hiçbir avantajı yoktur. Ancak yine, diğer yaklaşımlar da çok hızlı bir şekilde uygulanabilir. Ancak dezavantajlar var ve oldukça önemli:


    Kurabiye

    Genel ActionResult Çerezleri2 () (HttpCookie çerez \u003d new HttpCookie ("userName", HttpUtility.UrlEncode (Request.Form ["userName"])); cookie.Expires \u003d DateTime.UtcNow.AddHours (1); Response.Cookies.Add ( çerez); dönüş Görünümü ();)

    @using (Html.BeginForm ("Cookies3", "Home", FormMethod.Post)) (

    @ ($ "Merhaba (HttpUtility.UrlDecode (Request.Cookies [" kullanıcıAdı "]?. Değer))! Ne sipariş edeceksiniz?")

    }

    İÇİNDE bu yaklaşım oturum verilerini doğrudan formda saklamıyoruz, bunun yerine istemci ve sunucu arasında standart çerez mekanizmasını kullanıyoruz. Tüm kullanıcı verileri çerezlerde saklanır.

    Bu yaklaşımı seçerken, yine asıl sorun, sunucuya aktardığımız verilerimizin güvenliğidir - değiştirilmesi veya çalınması kolaydır, açık form... Ayrıca, istemcinin tarayıcı gizlilik ayarlarında sitelerden çerezlerin kabulü devre dışı bırakılırsa, bir oturumu sürdürmek için bu seçenek hiç çalışmayacaktır.

    Bu nedenle, önemli ve gizli verilerin girişler, şifreler, kart ve hesap numaraları, pasaport verileri, ikamet yeri gibi ilk iki yöntemle aktarılması kesinlikle önerilmez.

    Sunucu tarafı oturum yönetim mekanizması (Session, SessionState)

    Oturum mekanizmasının sunucu tarafında ve istemci tarafında nasıl çalıştığını görelim.

    Ne zaman standart ayarlar Oturum durumu işlemi, bir istemciden gelen bir dizi isteği izlemek için kullanılır. oturum tanımlama bilgisi. Algoritma aşağıdaki gibidir:

    1. Sunucuya yapılan kesinlikle her yeni istek için (farklı istemciler veya bir tane olmaları önemli değildir) ASP.NET, benzersiz bir oturum tanımlayıcısı oluşturur.
      Oturum tanımlayıcısı, özel bir algoritma kullanılarak 24 karakter uzunluğunda bir dizeye kodlanmış rastgele oluşturulmuş bir sayıdır. Dize, A'dan Z'ye kadar küçük harfli değişmez değerler ve 0'dan 5'e kadar sayılardan oluşur. Bir tanımlayıcı örneği hjnyuijl1pam3vox2h5i41in'dir
    2. Mevcut talep sırasında müşterinin verileri onunla daha fazla çalışmak için KAYDEDİLMEZSE, bu müşterinin oturumunun ömrü sona erer (fiilen başlamaz). Bu durumda, önceden oluşturulan oturum tanımlayıcısı geçersiz hale gelir (kullanılmadığı için). Böyle bir talebe yanıt olarak, müşteri onu yeni bir oturumla ilişkilendirecek hiçbir şey almaz.
    3. İstemci verileri (örneğin, ad, sevkiyat adresi) sunucuda depolanıyorsa, ASP.NET depolanan verileri önceden oluşturulmuş bir oturum kimliğiyle ilişkilendirir. Ardından, özel bir oturum çerezi oluşturulur ve bu tanımlayıcı da içine kaydedilir. Bu çerez, bir talebe yanıt olarak eklenir ve müşterinin tarayıcısında saklanır. Böylece, istemci ile sunucudaki kişiselleştirilmiş bilgileri arasında bir bağlantı oluşturulur. İçin yeni oturum bu müşteri oluşturuldu.
    4. Her bir sonraki talepte, müşteri sunucuya tanımlama bilgileri aracılığıyla kişisel bir oturum tanımlayıcısı gönderir. Sunucu, tanımlayıcılarla eşleşir ve mevcut oturum içinde istemciyi "tanır".
    5. Müşteri kişisel anahtarını ilettiği sürece oturum aktif olarak kabul edilir. Oturum, çeşitli nedenlerle, örneğin, sunucu tarafında manuel olarak veya belirli bir süre (zaman aşımı) sonra sona erebilir.

    Teoriden pratiğe geçelim. Bu algoritmayı programlayalım ve nasıl çalıştığını görelim. Bunun için özel bir HttpSessionState sınıfı kullanıyoruz. Bir denetleyicide çalışırken, HttpContext.Session özelliğini kullanabilirsiniz. Herhangi bir NameValueCollection'da olduğu gibi bir oturumla çalışmak çok basittir:

    Oturum ["userName"] \u003d Request.Form ["userName"]; bool isSessionNew \u003d Session.IsNewSession; string sessionId \u003d Session.SessionID;

    Bu kod parçasında, kullanıcı adını oturum durumuna yazıyoruz. Bu ismi bize gönderdiği html formundan alıyoruz. Ek olarak, özellikler aracılığıyla, bu oturumun henüz oluşturulup oluşturulmadığını, yani mevcut istek çerçevesinde (evet ise, IsNewSession özelliğinin değeri doğru olacaktır) ve oturumun benzersiz tanımlayıcısını öğreniriz. . Talebi işledikten sonra, bu tanımlayıcı otomatik olarak oturum tanımlama bilgisine (henüz değilse) kaydedilecek ve müşteriye yanıt olarak gönderilecektir.

    Müşterinin tarayıcısında, karşılık gelen çerezi ve oturumunun tanımlayıcısını gözlemleyebilirsiniz:

    Bu istemcinin bir sonraki talebinde, oturumdan önceden kaydedilmiş ismini okuyalım. Ayrıca oturumu sona erdireceğiz. Bu müşteri ile çalışma tamamlandı, örneğin tüm veriler işlendi ve mallar gönderildi.

    String userName \u003d Oturum ["userName"]. ToString (); // istek işleniyor ... Session.Abandon ();

    Gördüğünüz gibi oturumlarla çalışmak çok basit ve rahat. Bir oturumun işlenmesiyle ilişkili işlemlerin çoğu arka planda otomatik olarak gerçekleşir. Doğal olarak geliştirici, oturum işlemenin herhangi bir aşamasında müdahale edebilir ve kendi ayarlamalarını yapabilir.

    İşte en sık kullanılan HttpSessionState sınıfının en ilginç özelliklerine ve yöntemlerine bir göz atalım:

    Öğe - dizinine göre bir veri öğesi döndürür
    Öğe - anahtarıyla bir veri öğesi döndürür
    Kaldır (indeks) - bir veri öğesini indeksine göre kaldırır
    Kaldır (anahtar) - bir öğeyi anahtarıyla siler
    Açık () - tüm verileri siler
    Miktar - mevcut oturum için toplam veri öğesi sayısını döndürür
    Terk etmek () - oturumu zorla sonlandırın
    Oturum kimliği - mevcut oturumun tanımlayıcısını döndürür
    IsNewSession - oturum mevcut istek içinde oluşturulmuşsa true döndürür
    Zaman aşımı - Bir zaman aşımı nedeniyle oturum bitmeden önce istekler arasında izin verilen dakika sayısını döndürür (varsayılan olarak 20 dakika)

    HttpSessionState sınıfının üyeleri aracılığıyla veya uygulama yapılandırması () aracılığıyla bir oturumun ayarlarını kod içinde programlı olarak değiştirebilirsiniz. Örneğin:

    Yukarıdaki yapılandırmada, oturum zaman aşımının 40 dakika olacağını, kullanıcının oturum verilerinin rasgele erişim belleğioturum tanımlama bilgileri kullanılacak, biz de böyle bir tanımlama bilgisinin varsayılan adını kendi adımızla değiştirdik.

    Ve bir önemli güvenlik notu daha. Kullanıcının oturumunu Session.Abandon () yöntemiyle sonlandırdığınızda; SessionId'yi saklayan oturum tanımlama bilgisi kullanıcının tarayıcısında silinmez. Bu, eğer kullanıcı yakın gelecekte tarayıcıyı kapatmadan yeni bir oturum başlatırsa, yeni oturumuna aynı SessionId atanacağı anlamına gelir. Her yeni oturum için her zaman yeni bir benzersiz tanımlayıcı atamanız önerilir, bunun için oturum kapatıldıktan sonra oturum çerezini manuel olarak silmemiz gerekir:

    Session.Clear (); // oturumu temizle Session.Abandon (); // oturumu iptal edin // bu Response.Cookies.Add gibi tanımlama bilgilerini manuel olarak temizleyin (yeni HttpCookie ("ASP.NET_SessionId", "")); // veya Response.Cookies ["ASP.NET_SessionId"] süresini kısaltın. Expires \u003d DateTime.Now.AddYears (-30); //ASP.NET_SessionId, oturum tanımlama bilgisi için varsayılan addır, kendi

    Kullanıcı oturumunun durumu, oturumlar kullanılarak ASP.NET platformunda bu şekilde izlenir. Bu yaklaşım standarttır ve kullanıcı hakkındaki bilgilerin depolanması ve sunucuya yapılan istekler arasında tanımlanması gerektiğinde kullanılması tavsiye edilir.

    Merhaba sevgili topluluk.

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

    Bu makalenin amacı PHP'de oturum kullanmanın güçlüklerini vurgulamaktır. Elbette PHP belgeleri ve pek çok örnek var ve bu makale tam rehber... Oturumlarla çalışmanın bazı nüanslarını ortaya çıkarmak ve geliştiricileri gereksiz zaman kaybından korumak için tasarlanmıştır.

    Oturumlar için en yaygın kullanım durumu elbette kullanıcı yetkilendirmesidir. Yeni zorluklar ortaya çıktıkça bunu tutarlı bir şekilde geliştirebilmemiz için en temel uygulamayla başlayalım.

    (Yer ve zamandan tasarruf etmek için, burada güzel bir sınıf hiyerarşisi, kapsamlı hata işleme ve diğer doğru şeylerle tam teşekküllü bir test uygulaması oluşturmak yerine, kendimizi yalnızca oturumlarla çalışma işlevleriyle örneklerle sınırlayacağız).

    İşlev startSession () (// Oturum zaten başlatılmışsa, yürütmeyi durdurun ve TRUE // (php.ini ayarlar dosyasındaki session.auto_start parametresi devre dışı bırakılmalıdır - varsayılan değer) döndürürse (session_id ()) true; else return session_start (); // Not: 5.3.0 sürümünden önce, session_start () işlevi hata durumunda bile TRUE döndürdü. // 5.3.0'ın altında bir sürüm kullanıyorsanız ek doğrulama session_id ( ) // session_start ()) işlevini çağırdıktan sonra destroySession () (if (session_id ()) (// Etkin bir oturum varsa, setcookie (oturum_adı (), session_id (), time () - 60 * 60 * 24); // ve session_unset (); session_destroy ();)) oturumunu yok et

    Not: Okuyucunun PHP oturumları hakkında temel bilgiye sahip olduğu varsayılır, bu nedenle burada session_start () ve session_destroy () işlevlerinin çalışma prensibini ele almayacağız. Giriş formu düzeninin ve kullanıcı kimlik doğrulamasının görevleri makalenin konusuyla ilgili değildir, bu nedenle bunları da atlayacağız. Sonraki her istekte kullanıcıyı tanımlamak için, başarılı oturum açma anında, kullanıcı kimliğini bir oturum değişkenine (örneğin, kullanıcı kimliği adıyla) kaydetmemiz gerektiğini hatırlatmama izin verin, bu sonraki tüm taleplerde mevcut olacak seans süresi içindeki talepler. Ayrıca startSession () fonksiyonumuzun sonucunun işlenmesini uygulamak da gereklidir. İşlev FALSE döndürürse, tarayıcıda oturum açma formunu görüntüleyin. İşlev TRUE döndürürse ve yetkili kullanıcının tanımlayıcısını içeren oturum değişkeni (bizim durumumuzda, kullanıcı kimliği) mevcutsa - yetkili kullanıcının sayfasını görüntüleyin (hata işleme hakkında daha fazla bilgi için, 2013-06'dan itibaren eke bakın- 07 oturum değişkenleri bölümünde).

    Şimdiye kadar her şey net. Sorular, kullanıcı hareketsizliğinin kontrolünü uygulamak (oturum zaman aşımı), birkaç kullanıcının aynı anda bir tarayıcıda çalışmasını sağlamak ve ayrıca oturumları yetkisiz kullanımdan korumak gerektiğinde başlar. Bu konuya aşağıda tekrar değinilecektir.

    Yerleşik PHP araçlarıyla kullanıcı hareketsizliğini kontrol etme

    Kullanıcılar için her türlü konsol geliştiricileri arasında sıklıkla ortaya çıkan ilk soru, kullanıcının hareketsiz kalması durumunda oturumun otomatik olarak sonlandırılmasıdır. PHP'nin yerleşik yeteneklerini kullanmaktan daha kolay olamazdı. (Bu seçenek özellikle güvenilir ve esnek değildir, ancak eksiksizlik açısından ele alalım).

    İşlev startSession () (// Kullanıcı hareketsizlik zaman aşımı (saniye cinsinden) $ sessionLifetime \u003d 300; if (session_id ()) return true; // Çerez ömrünü ayarlayın ini_set ("session.cookie_lifetime", $ sessionLifetime); // kullanıcı hareketsizlik zaman aşımı ayarlandı, sunucuda oturum ömrünü ayarlayın // Not: Bir üretim sunucusu için, php.ini dosyasında bu parametrelerin önceden ayarlanması önerilir if ($ sessionLifetime) ini_set ("session.gc_maxlifetime", $ sessionLifetime ); if (session_start ()) (setcookie (session_name (), session_id (), time () + $ sessionLifetime); true döndür;) aksi takdirde false döndür;)

    Birkaç açıklama. Bildiğiniz gibi PHP, hangi oturumun başlatılacağını tarayıcının istek başlığında geçirdiği tanımlama bilgisinin adıyla belirler. Tarayıcı da bu çerezi, session_start () işlevinin yerleştirdiği sunucudan alır. Tanımlama bilgisinin tarayıcıda süresi dolmuşsa, istekte iletilmeyecektir, bu da PHP'nin hangi oturumun başlayacağını belirleyemeyeceği ve bunu yeni bir oturum oluşturduğunu kabul edeceği anlamına gelir. Parametre pHP ayarları Kullanıcının hareketsizlik zaman aşımına ayarlanan session.gc_maxlifetime, PHP oturumunun ömrünü belirler ve sunucu tarafından kontrol edilir. Oturum ömrü denetimi şu şekilde çalışır (burada, PHP'de en yaygın ve varsayılan sürüm olarak geçici dosyalarda bir oturum depolama örneğini ele alıyoruz).

    Yeni bir oturum yaratılırken, PHP settings parametresi session.save_path içindeki oturumları depolamak için dizin olarak ayarlanan dizinde sess_ adında bir dosya oluşturulur. nerede - oturum tanımlayıcı. Ayrıca, her istekte, mevcut bir oturumu başlatırken, PHP bu dosyanın değişiklik zamanını günceller. Böylece, sonraki her istekte PHP, mevcut saat ile oturum dosyasının son değiştirilme zamanı arasındaki farka göre, oturumun etkin olup olmadığını veya ömrünün dolmuş olup olmadığını belirleyebilir. (Eski oturum dosyalarını silme mekanizması bir sonraki bölümde daha ayrıntılı olarak tartışılmaktadır).

    Not: Burada session.gc_maxlifetime parametresinin bir sunucudaki (daha doğrusu tek bir ana pHP süreci). Uygulamada, bu, sunucuda birkaç site çalışıyorsa ve her birinin kendi kullanıcıların etkinlik dışı kalma zaman aşımına sahip olması durumunda, bu parametrenin sitelerden birinde ayarlanması diğer siteler için kurulumuna yol açacağı anlamına gelir. Aynı şey paylaşılan barındırma için de geçerlidir. Bu durumu önlemek için, bir sunucu içindeki 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şlevini çağırarak yapılır. Bundan sonra, her sitenin oturumları ayrı dizinlerde saklanacak ve sitelerden birinde ayarlanan session.gc_maxlifetime parametresi yalnızca oturumu için geçerli olacaktır. Bu durumu ayrıntılı olarak ele almayacağız, özellikle de kullanıcının hareketsizliğini kontrol etmek için daha esnek bir seçeneğimiz olduğu için.

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

    Görünüşe göre önceki seçenek, tüm basitliği için (sadece birkaç ek kod satırı) ihtiyacımız olan her şeyi veriyor. Peki ya her istek kullanıcı etkinliğinin bir sonucu olarak kabul edilemiyorsa? Örneğin, sayfada, sunucudan güncellemeleri almak için periyodik olarak AJAX isteğinde bulunan bir zamanlayıcı vardır. Bu tür bir istek, kullanıcı etkinliği olarak kabul edilemez, bu da oturum ömrünün otomatik olarak uzatılmasının bu durumda doğru olmadığı anlamına gelir. Ancak PHP'nin, session_start () işlevi her çağrıldığında oturum dosyasının değişiklik zamanını otomatik olarak güncellediğini biliyoruz, bu da herhangi bir isteğin oturum ömrünün uzamasına neden olacağı ve kullanıcı hareketsizlik zaman aşımının asla gerçekleşmeyeceği anlamına gelir. Buna ek olarak, session.gc_maxlifetime parametresinin incelikleri ile ilgili önceki bölümdeki son not, uygulanması çok kafa karıştırıcı ve karmaşık görünebilir.

    Bu sorunu çözmek için yerleşik olanı kullanmayı bırakalım pHP mekanizmaları ve kullanıcıların hareketsizlik zamanını kendi başımıza kontrol etmemizi sağlayacak birkaç yeni oturum değişkenini tanıtın.

    İşlev startSession ($ isUserActivity \u003d true) ($ sessionLifetime \u003d 300; if (session_id ()) return true; // Tarayıcı kapanana kadar çerez ömrünü ayarlayın (sunucu tarafındaki her şeyi kontrol edeceğiz) ini_set ("session.cookie_lifetime ", 0); if (! Session_start ()) return false; $ t \u003d time (); if ($ sessionLifetime) (// Kullanıcı hareketsizlik zaman aşımı ayarlandıysa, // son kullanıcı etkinliğinden bu yana geçen süreyi kontrol et / / (son etkinlik oturumu değişkeni güncellendiğinde son isteğin zamanı) if (isset ($ _ SESSION ["son etkinlik"]) && $ t - $ _ SESSION ["son etkinlik"]\u003e \u003d $ oturum Ömrü) (// Son kullanıcı etkinliği / / daha fazla hareketsizlik zaman aşımından bu yana geçen süre, ardından oturumun süresi dolmuştur ve oturumu sonlandırmanız gerekir destroySession (); return false;) else (// Zaman aşımı henüz gerçekleşmediyse, // ve eğer istek, kullanıcı etkinliğinin bir sonucu olarak geldi, // son etkinlik değişkenini mevcut vr'nin değeriyle güncelle emeny, // böylelikle oturum süresini başka bir oturum Ömrü saniye kadar uzatırsanız ($ isUserActivity) $ _SESSION ["lastactivity"] \u003d $ t; )) true döndürür; )

    Özetleyelim. Her istekte, son kullanıcı etkinliğinden geçerli ana kadar zaman aşımına ulaşılıp ulaşılmadığını kontrol ederiz ve bu zamana ulaşılmışsa, oturumu yok eder ve işlevin yürütülmesini kesintiye uğratarak FALSE döndürür. Zaman aşımına ulaşılmadıysa ve TRUE değerine sahip $ isUserActivity parametresi işleve geçirilirse, son kullanıcı etkinliğinin zamanını güncelleriz. Tek yapmamız gereken, çağıran komut dosyasında isteğin kullanıcı etkinliğinin sonucu olup olmadığını belirlemek ve değilse, startSession işlevini $ isUserActivity parametresinin değeri FALSE'a eşit olacak şekilde çağırmaktır.

    2013-06-07 itibarıyla güncelleme
    SessionStart () işlevinin sonucunun işlenmesi

    Yorumlarda, YANLIŞ döndürmenin hatanın nedenini tam olarak anlamadığını fark ettiler ve bu kesinlikle doğru. Burada ayrıntılı hata işlemeyi yayınlamadım (makalenin hacmi zaten küçük değil), çünkü bu doğrudan makalenin konusuyla ilgili değil. Ancak yorumlar göz önüne alındığında, açıklığa kavuşturacağım.

    Gördüğünüz gibi, sessionStart işlevi iki durumda FALSE döndürebilir. Ya oturum bazı dahili sunucu hataları nedeniyle başlatılamadı (örneğin, php.ini içindeki yanlış oturum ayarları) ya da oturumun süresi doldu. İlk durumda, kullanıcıyı, sunucuda sorun olduğunu belirten bir hata ve bir destekle iletişim kurma biçimi içeren bir sayfaya yönlendirmeliyiz. İkinci durumda, kullanıcıyı giriş formuna aktarmalı ve içinde oturumun sona erdiğine dair ilgili bir mesaj görüntülemeliyiz. Bunu yapmak için, hata kodlarını girmemiz ve FALSE yerine karşılık gelen kodu döndürmemiz ve çağrı yönteminde kontrol edip buna göre hareket etmemiz gerekir.

    Şimdi, sunucudaki oturum hala mevcut olsa bile, kullanıcı hareketsizlik zaman aşımı sona erdiyse, ona ilk erişimde yok edilecek. Ve bu, genel PHP ayarlarında hangi oturum ömrünün ayarlandığına bakılmaksızın gerçekleşir.

    Not: Tarayıcı kapatılırsa ve oturum adı çerezi otomatik olarak imha edilirse ne olur? Tarayıcının bir sonraki açılışında sunucuya yapılan istek, oturum tanımlama bilgilerini içermeyecek ve sunucu, bir oturum açamayacak ve kullanıcının etkin olmadığı zaman aşımını kontrol edemeyecektir. Bizim için bu, yeni bir oturum oluşturmakla eşdeğerdir ve işlevselliği veya güvenliği hiçbir şekilde etkilemez. Fakat akla uygun bir soru ortaya çıkıyor - zaman aşımı sona erdikten sonra şimdiye kadar onu yok ettiysek eski oturumu kim yok edecek? Yoksa şimdi oturum dizininde sonsuza kadar mı kalacak? Eski oturumları temizlemek için PHP'nin çöp toplama adı verilen bir mekanizması vardır. Sunucuya yapılacak bir sonraki talepte başlar ve tüm eski oturumları tarihe göre temizler. son değişiklik oturum dosyaları. Ancak, çöp toplama mekanizması sunucuya yapılan her istekte başlamaz. Başlatma sıklığı (daha doğrusu, olasılık) iki ayar parametresi session.gc_probability ve session.gc_divisor tarafından belirlenir. Birinci parametrenin ikinciye bölünmesinin sonucu, çöp toplama mekanizmasının başlama olasılığıdır. Bu nedenle, oturum temizleme mekanizmasının sunucuya her istekte başlaması için, bu parametrelerin eşit değerlere, örneğin "1" değerine ayarlanması gerekir. Bu yaklaşım, oturum dizininin temiz olmasını sağlar, ancak açık bir şekilde sunucu için fazla yük oluşturur. Bu nedenle, üretim sistemlerinde, session.gc_divisor varsayılan olarak 1000'e ayarlanmıştır, bu da çöp toplama motorunun 1/1000 olasılıkla başlayacağı anlamına gelir. Php.ini dosyanızda bu ayarları denerseniz, yukarıdaki durumda, tarayıcı tüm tanımlama bilgilerini kapattığında ve temizlediğinde, oturum dizininde bir süreliğine hala eski oturumlar olduğunu fark edeceksiniz. Ama bu seni endişelendirmemeli çünkü daha önce de belirtildiği gibi, bu hiçbir şekilde mekanizmamızın güvenliğini etkilemez.

    2013-06-07 itibarıyla güncelleme

    Oturum dosyasını engellediği için komut dosyalarının asılı kalmasını önleme

    Yorumlarda, oturum dosyasının engellenmesi nedeniyle aynı anda çalışan komut dosyalarının donması sorununu gündeme getirdiler (en parlak seçenek - uzun anket).

    Başlangıç \u200b\u200bolarak, bu sorunun doğrudan sunucu yüküne veya kullanıcı sayısına bağlı olmadığını not ediyorum. Elbette, istek ne kadar fazlaysa komut dosyaları o kadar yavaş çalışır. Ancak bu dolaylı bir bağımlılıktır. Sorun, sunucu bir kullanıcı adına birkaç istek aldığında yalnızca bir oturumda ortaya çıkar (örneğin, biri uzun anket ve geri kalanı sıradan isteklerdir). Her istek aynı oturum dosyasına erişmeye çalışır ve önceki istek dosyanın kilidini açmadıysa, sonraki istek beklemede kalır.

    Oturum dosyalarını engellemeyi minimumda tutmak için, oturum değişkenleriyle tüm eylemler gerçekleştirildikten hemen sonra session_write_close () işlevini çağırarak oturumu kapatmanız şiddetle önerilir. Pratikte bu, her şeyi oturum değişkenlerinde saklamamanız ve betiğin yürütülmesi boyunca bunlara başvurmamanız gerektiği anlamına gelir. Ve bazı çalışma verilerini oturum değişkenlerinde saklamak gerekirse, o zaman oturumun başında hemen okuyun, daha sonra kullanmak için yerel değişkenlere kaydedin ve oturumu kapatın (yani, oturumu kapatmak değil, session_write_close işlevini kullanarak kapatın. session_destroy kullanarak).

    Örneğimizde bu, bir oturumu açtıktan hemen sonra, yaşam süresini ve yetkili bir kullanıcının varlığını kontrol etmeliyiz, uygulama için gerekli tüm ek oturum değişkenlerini (varsa) okuyup kaydetmemiz ve ardından session_write_close ( ) ve uzun bir anket veya normal bir istek olsun, bir komut dosyasının yürütülmesine devam edin.

    Oturumların yetkisiz kullanımdan korunması

    Bir durum hayal edelim. Kullanıcılarınızdan biri, tarayıcı çerezlerini (oturumumuzun saklandığı) soyan ve belirtilen e-postaya gönderen bir Truva atı takıyor. Saldırgan çerezi alır ve yetkili kullanıcımız adına sahte bir talepte bulunmak için kullanır. Sunucu, bu isteği yetkili bir kullanıcıdan gelmiş gibi başarıyla kabul eder ve işler. IP adresinin ek doğrulaması uygulanmazsa, bu tür bir saldırı, tüm sonuçlarla birlikte kullanıcının hesabının başarılı bir şekilde hacklenmesine yol açacaktır.

    Bu neden mümkün? Açıkçası, ad ve oturum tanımlayıcı oturumun tüm ömrü boyunca her zaman aynı olduğundan ve bu verileri alırsanız, başka bir kullanıcı adına (doğal olarak bu oturumun ömrü içinde) istekleri özgürce gönderebilirsiniz. Belki de bu en yaygın saldırı türü değildir, ancak teoride her şey oldukça uygulanabilir görünüyor, özellikle de böyle bir Truva atının kullanıcının tarayıcı çerezlerini soymak için yönetici haklarına ihtiyaç duymadığı düşünüldüğünde.

    Bu tür saldırılara karşı nasıl savunma yapabilirsiniz? Yine, açık bir şekilde, oturum tanımlayıcısının ömrünü sınırlayarak ve tanımlayıcıyı bir oturum içinde periyodik olarak değiştirerek. Ayrıca oturumun adını değiştirebilir, eskisini tamamen silip yeni bir oturum oluşturabilir, tüm oturum değişkenlerini eskisinden ona kopyalayabiliriz. Ancak bu, yaklaşımın özünü etkilemez, bu nedenle, basitlik için kendimizi yalnızca oturum kimliğiyle sınırlayacağız.

    Açıktır ki, oturum tanımlayıcısının ömrü ne kadar kısa olursa, bir saldırganın bir kullanıcının isteğini taklit etmek için tanımlama bilgilerini elde etmesi ve kullanması o kadar az olacaktır. İdeal olarak, başka birinin oturumunu kullanma olasılığını en aza indirmek için her istek için yeni bir tanımlayıcı kullanılmalıdır. Ancak, oturum kimliği yenileme zamanının keyfi olarak ayarlandığı genel durumu ele alacağız.

    (Kodun daha önce tartışılmış olan kısmını atlayalım).

    Function startSession ($ isUserActivity \u003d true) (// Session ID lifetime $ idLifetime \u003d 60; ... if ($ idLifetime) (// Oturum kimliği ömrü ayarlanmışsa, // oturum oluşturulduğundan beri geçen süreyi kontrol edin veya son yeniden oluşturma // (oturum değişkeni başlangıç \u200b\u200bzamanı güncellendiğinde son isteğin zamanı) if (isset ($ _ SESSION ["başlangıç \u200b\u200bzamanı"])) (if ($ t - $ _ SESSION ["başlangıç \u200b\u200bzamanı"]\u003e \u003d $ idLifetime) (// Oturum kimliğinin süresi doldu // Yeni bir kimlik oluştur session_regenerate_id (true); $ _SESSION ["starttime"] \u003d $ t;)) else (// Oturum yeni oluşturulmuşsa buraya geliyoruz // Set şu andaki oturum kimliği oluşturma zamanı $ _SESSION ["başlangıç \u200b\u200bzamanı"] \u003d $ t;)) doğru döndür;)

    Bu nedenle, yeni bir oturum oluştururken (kullanıcı başarıyla oturum açtığında meydana gelir), bizim için oturum kimliğinin son neslinin zamanını saklayan oturum değişkeninin başlangıç \u200b\u200bsaatini mevcut sunucu zamanına eşit bir değere ayarlıyoruz. Ayrıca, her istekte, tanımlayıcının son neslinden bu yana yeterli zamanın (idLifetime) geçip geçmediğini kontrol ediyoruz ve varsa yeni bir tane oluşturuyoruz. Böylelikle, tanımlayıcının belirtilen ömrü içinde, yetkili kullanıcının çerezini alan saldırgan onu kullanmayı başaramazsa, sahte istek sunucu tarafından yetkisiz olarak kabul edilecek ve saldırgan oturum açma sayfasına yönlendirilecektir.

    Not: Yeni oturum kimliği, session_regenerate_id () işlevi çağrıldığında, session_start () işlevine benzer şekilde yeni bir çerez gönderen tarayıcı çerezine girer, böylece çerezleri kendimiz güncellememiz gerekmez.

    Oturumlarımızı mümkün olduğunca güvenli hale getirmek istiyorsak, tanımlayıcının yaşam süresini bire ayarlamak veya hatta session_regenerate_id () işlevini parantezlerin dışına koymak ve tüm kontrolleri kaldırmak yeterlidir, bu da tanımlayıcının yeniden oluşturulmasına yol açar. her istekte. (Bu yaklaşımın performans üzerindeki etkisini test etmedim ve yalnızca session_regenerate_id (true) işlevinin yalnızca 4 eylem gerçekleştirdiğini söyleyebilirim: yeni bir tanımlayıcı oluşturmak, oturum tanımlama bilgisinden bir başlık oluşturmak, eskisini silmek ve yeni bir oturum dosyası oluşturma).

    Lirik kazı: Truva Atı, saldırgana tanımlama bilgilerini göndermeyecek kadar akıllı çıkarsa, ancak kendisi tanımlama bilgisini alır almaz önceden hazırlanmış sahte bir istek göndermeyi düzenlerse, yukarıda açıklanan yöntem büyük olasılıkla koruma sağlayamayacaktır. Bu tür bir saldırıya karşı, çünkü Truva Atı tanımlama bilgisini aldığı zaman ile sahte olanı gönderdiği zaman arasında, istek arasında neredeyse hiçbir fark olmayacak ve bu noktada oturum kimliğinin yeniden oluşturulmayacağı çok muhtemeldir.

    Birden fazla kullanıcı adına tek bir tarayıcıda aynı anda çalışabilme yeteneği

    Dikkate almak istediğim son görev, birkaç kullanıcı için aynı anda bir tarayıcıda çalışma imkanı. Bu özellik, eşzamanlı kullanıcı çalışmasını taklit etmeniz gerektiğinde özellikle test aşamasında kullanışlıdır ve bunu mevcut tüm cephaneliği kullanmak veya tarayıcının birden fazla örneğini gizli modda açmak yerine favori tarayıcınızda yapmanız önerilir.

    Önceki örneklerimizde, oturum adını açıkça belirlemedik, bu nedenle varsayılan PHP adı (PHPSESSID) kullanıldı. Bu, şimdiye kadar oluşturduğumuz tüm oturumların tarayıcıya PHPSESSID adı altında çerezler gönderdiği anlamına gelir. Açıktır ki, çerezin adı her zaman aynıysa, o zaman aynı tarayıcı içinde aynı ada sahip iki oturum düzenlemenin bir yolu yoktur. Ancak her kullanıcı için farklı bir oturum adı kullanırsak sorun çözülürdü. Öyleyse hadi yapalım.

    İşlev startSession ($ isUserActivity \u003d true, $ prefix \u003d null) (... if (session_id ()), true döndürür; // Parametrelerde kullanıcı öneki geçirilirse, // bunu içeren benzersiz bir oturum adı ayarlayın önek, // aksi takdirde tüm kullanıcılar için ortak bir ad belirleyin (örneğin, BENİMİM) session_name ("MYPROJECT". ($ prefix? "_". $ prefix: "")); ini_set ("session.cookie_lifetime", 0) ; eğer (! session_start ()) yanlış döndürür; ...)

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

    Sonuç

    Sonuç olarak, birlikte çalışmak için işlevlerimizin eksiksiz son kodunu vereceğim pHP oturumlarıyukarıda tartışılan tüm görevleri içerir.

    İşlev startSession ($ isUserActivity \u003d true, $ prefix \u003d null) ($ sessionLifetime \u003d 300; $ idLifetime \u003d 60; eğer (session_id ()) true döndürürse; session_name ("MYPROJECT". ($ Önek? "_". $ Önek: "")); ini_set ("session.cookie_lifetime", 0); if (! session_start ()) false döndür; $ t \u003d time (); if ($ sessionLifetime) (if (isset ($ _ SESSION ["lastactivity" ]) && $ t - $ _ SESSION ["lastactivity"]\u003e \u003d $ sessionLifetime) (destroySession (); return false;) else (if ($ isUserActivity) $ _SESSION ["lastactivity"] \u003d $ t;)) if ( $ idLifetime) (if (isset ($ _ SESSION ["başlangıç \u200b\u200bzamanı"])) (if ($ t - $ _ SESSION ["başlangıç \u200b\u200bzamanı"]\u003e \u003d $ idLifetime) (session_regenerate_id (true); $ _SESSION ["başlangıç \u200b\u200bzamanı"] \u003d $ t;)) else ($ _SESSION ["başlangıç \u200b\u200bzamanı"] \u003d $ t;)) true döndür;) function destroySession () (if (session_id ()) (session_unset (); setcookie (session_name (), session_id () , time () -60 * 60 * 24); session_destroy ();))

    Umarım bu makale, oturum mekanizmasına hiç girmemiş olanlar için biraz zaman kazandırır ve PHP'yi yeni tanımaya başlayanlar için bu mekanizmayı yeterince kavrayacaktır.

    Modülde Aktif oturumlar kontrol paneliyle çalışan kullanıcıların listesini istediğiniz zaman şurada görüntüleyebilirsiniz: şu an, Kullanıcının eriştiği IP adresi ve bu kullanıcıdan son komutun alınmasından bu yana geçen süre.

    Gerekirse, seçilen kullanıcının oturumunu sonlandırabilirsiniz.

    "Etkin oturumlar" modülü

    Mevcut bağlantılarla ilgili bilgileri görüntüleme

    • Oturum kimliği - oturumu kontrol paneliyle tanımlayan benzersiz bir numara. Varsayılan olarak, bilgiler tabloda 60 dakika süreyle görüntülenir.
    • Kullanıcı - o anda sisteme bağlı olan kullanıcının adı.
    • Giriş - bu kullanıcının kontrol paneline erişim düzeyi (örneğin, süper kullanıcı, sunucu yöneticisi, kullanıcı vb.).
    • IP adresi - erişimin gerçekleştirildiği uzak IP adresi.
    • Beklenti - Kontrol panelinin kullanıcıdan son komutu aldığı andan itibaren geçen süre.
    • Aktif istekler - aktif isteklerin sayısı.

    Seans sonu

    Kontrol paneliyle belirli bir oturumu sonlandırmak için, aktif oturumlar listesinden gerekli satırları seçin ve "Bitir" düğmesini tıklayın.

    Kazara silmeleri önlemek için, kontrol paneli eyleminizi onaylamanızı veya iptal etmenizi isteyecektir. Onay penceresinde "Tamam" ı tıklarsanız, seçilen oturumlar sonlandırılacaktır.

    Oturum sonlandırılmışsa, kontrol paneliyle çalışmaya devam etmek için kullanıcının tekrar oturum açması gerekir.

    Bu form bir destek araması değildir.
    Sizi tanımlayamayız ve mesajınıza cevap veremeyiz.

    Oturum (Latince - sessio - toplantı, İngilizce - oturum), ilk bağlantıdan son bağlantıya kadar kullanıcının İnternet üzerindeki çalışmasını kapsayan bir süredir. İlk ve son talepler arasındaki zaman farkı olarak hesaplanır. Bununla birlikte, son sayfa kullanıcı tarafından farklı zamanlarda görüntülenebilir ve bu nedenle, iki istek arasındaki süreyi ölçmek daha zor hale gelir.

    Oturum HTTP ve ÇEREZLER ile nasıl ilişkilidir?

    HTTP protokolü açısından bir oturumun ne olduğu açıklanabilir. Tek başına, bu protokol iki işlem arasında durumu korumanın bir yolunu sağlamaz. Yani, basitçe söylemek gerekirse, bir sayfayı açıp ondan diğerine geçerek, HTTP her iki isteğin de aynı kullanıcıya ait olduğunu belirleyemeyecektir. Ve kurtarma oturumu yönetimine (oturumlarımız) özel bir izleme yöntemi gelir.
    Dolayısıyla, bir oturum nedir sorusuna cevap vererek, bir kullanıcıdan gelen ardışık HTTP istekleri arasında veri transferini kolaylaştıran yardımcı bir mantıksal nesne olduğunu söyleyebiliriz.
    Çerezler, oturum gibi, farklı sayfalarda gezinirken kullanıcı hakkındaki bilgileri depolar ve protokolün işleyişini iyileştirir. Ancak verilerin sunucudaki geçici dosyalarda depolandığı ikinciden farklı olarak, bunları kullanıcının bilgisayarına küçük parçalar halinde kaydederler.

    Seanslar ne içindir?

    Forumlar, mesaj panoları ve çevrimiçi mağazalar gibi sitelerle çalışırken oturumların kullanılması zorunlu hale gelir, çünkü bu durumda, kullanıcı verilerini birkaç sayfaya kaydetmeniz gerekir.

    Oturum aşamaları

    Tüm seans üç aşamaya ayrılabilir:

    • bir oturum açma (bir kullanıcı belirli bir siteyle çalışmaya başladığında),
    • oturum değişkenlerinin muhasebesi (farklı sayfalara geçerken),
    • oturumun sonu.

    Oturum verilerinin üçüncü taraf bir sunucuda saklanması nedeniyle, en iyisi içlerinde büyük miktarda bilgi depolamak değil, tanımlama bilgilerini kullanmaktır.