Menü
Bedava
kayıt
ev  /  Gezginler/ Çerez ömrü php. PHP çerezleri - oluştur, oku, sil

Php çerez ömrü. PHP çerezleri - oluştur, oku, sil

Merhaba sevgili topluluk.

Öncelikle çok faydalı bir kaynak olduğu için teşekkür etmek istiyorum. Bir kereden fazla burada birçok ilginç fikir ve pratik tavsiye buldum.

Bu makalenin amacı, PHP'de oturum kullanmanın tuzaklarını vurgulamaktır. Tabii ki, PHP belgeleri ve bir ton örnek var ve bu makalenin amacı bu değil. eksiksiz rehber... Oturumlarla çalışmanın bazı nüanslarını ortaya çıkarmak ve geliştiricileri gereksiz yere zaman kaybetmekten 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 tutarlı bir şekilde geliştirebilmemiz için en temel uygulamayla başlayalım.

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

startSession () işlevi (// Oturum zaten başlatılmışsa, yürütmeyi durdurun ve TRUE 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 ()) return true; else return session_start (); // Not: 5.3.0 sürümünden önce, session_start () işlevi hata durumunda bile DOĞRU döndürdü. // 5.3.0'ın altında bir sürüm kullanıyorsanız, ek doğrulama session_id yapın ( ) // session_start () işlevini ç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 session_unset ( ); session_destroy ();)) oturumunu yok edin

Not: Okuyucunun temel PHP oturumları bilgisine sahip olduğu varsayıldığından, session_start() ve session_destroy() işlevlerinin nasıl çalıştığını ele almayacağız. Oturum açma formunun düzeni ve kullanıcı doğrulama görevleri makalenin konusu ile ilgili değildir, bu yüzden onları da atlayacağız. Size hatırlatmama izin verin, sonraki her istekte kullanıcıyı tanımlamak için, başarılı oturum açma anında, kullanıcı kimliğini sonraki tüm sürümlerde kullanılabilecek bir oturum değişkenine (örneğin, kullanıcı kimliği adıyla) kaydetmemiz gerekir. oturumun ömrü boyunca istekler. Ayrıca startSession() fonksiyonumuzun sonucunun işlenmesini de uygulamak gerekiyor. İşlev YANLIŞ döndürürse, oturum açma formunu tarayıcıda görüntüleyin. İşlev DOĞRU döndürürse ve yetkili kullanıcının tanımlayıcısını (bizim durumumuzda kullanıcı kimliği) içeren oturum değişkeni varsa, yetkili kullanıcının sayfasını görüntüleyin (hata işleme hakkında daha fazla ayrıntı için, 2013-06- ekine bakın). 07, oturum değişkenleri bölümünde).

Buraya kadar her şey açık. Sorular, kullanıcı hareketsizliği (oturum zaman aşımı) denetiminin uygulanması, birkaç kullanıcının aynı anda tek bir tarayıcıda çalışmasına ve ayrıca oturumların yetkisiz kullanıma karşı korunması 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ü 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. PHP'nin yerleşik yetenekleriyle bunu yapmak daha kolay olamazdı. (Bu seçenek çok güvenilir ve esnek değildir, ancak eksiksiz olması için düşünelim).

fonksiyon startSession () (// Kullanıcı hareketsizlik zaman aşımı (saniye olarak) $ sessionLifetime = 300; if (session_id ()) return true; // Çerez ömrünü ayarlayın ini_set ("session.cookie_lifetime", $ sessionLifetime); // Eğer kullanıcı hareketsizliği zaman aşımı ayarlandı, sunucuda oturum ömrünü ayarlayın // Not: Bir üretim sunucusu için, php.ini dosyasında bu parametreleri önceden ayarlamanız önerilir if ($ sessionLifetime) ini_set ("session.gc_maxlifetime", $ sessionLifetime ); if (session_start ( )) (setcookie (session_name (), session_id (), time () + $ sessionLifetime); true döndürme;) yoksa false döndürme;)

Birkaç açıklama. Bildiğiniz gibi PHP, tarayıcı tarafından istek başlığında iletilen çerezin adıyla hangi oturumun başlayacağını belirler. Tarayıcı da bu tanımlama bilgisini session_start() işlevinin yerleştirdiği sunucudan alır. Çerezin tarayıcıda süresi dolmuşsa, istekte iletilmez, bu da PHP'nin hangi oturumun başlayacağını belirleyemeyeceği ve bunu yeni bir oturum oluşturma olarak kabul edeceği anlamına gelir. Parametre PHP ayarları Kullanıcı hareketsizliği zaman aşımına ayarlanan session.gc_maxlifetime, PHP oturum ömrünü ayarlar ve sunucu tarafından izlenir. Oturum yaşam boyu denetimi aşağıdaki gibi çalışır (burada PHP'deki en yaygın ve varsayılan sürüm olarak geçici dosyalardaki bir oturum depolama örneğini ele alıyoruz).

Yeni bir oturum oluşturulurken, PHP ayarları parametresi session.save_path içinde oturumları depolamak için dizin olarak ayarlanan dizinde sess_ adlı bir dosya oluşturulur. , nerede - oturum tanımlayıcısı. Ayrıca, her istekte, mevcut bir oturumun başlatıldığı anda PHP bu dosyanın değişiklik zamanını günceller. Bu nedenle, her bir sonraki istekte PHP, geçerli saat ile oturum dosyasının son değişiklik zamanı arasındaki farka göre, oturumun etkin olup olmadığını veya kullanım süresinin 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 sunucu içindeki (daha doğrusu, bir ana sunucu içindeki) tüm oturumları etkilediğine dikkat edilmelidir. PHP süreci). Pratikte bu, sunucuda birkaç site çalışıyorsa ve her birinin kendi kullanıcı hareketsizliği zaman aşımına sahip olması durumunda, bu parametrenin sitelerden birine ayarlanması, diğer siteler için de yüklenmesine yol açacağı anlamına gelir. Aynı şey paylaşılan barındırma için de geçerlidir. Bu durumdan kaçınmak için, bir sunucu içindeki her site için ayrı oturum dizinleri kullanılır. Oturum dizinine giden yolun ayarlanması, 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 oturumu için geçerli olacaktır. Özellikle stokta kullanıcının hareketsizliğini kontrol etmek için 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ği için (sadece birkaç ek kod satırı) ihtiyacımız olan her şeyi veriyor. Ama ya her istek, kullanıcı etkinliğinin bir sonucu olarak kabul edilemezse? Örneğin, sayfanın sunucudan güncellemeleri almak için periyodik olarak bir AJAX isteğinde bulunan bir zamanlayıcısı vardır. Bu tür bir istek, kullanıcı etkinliği olarak kabul edilemez; bu, bu durumda oturum ömrünün otomatik olarak uzatılmasının doğru olmadığı anlamına gelir. Ancak, PHP'nin, session_start () işlevine yapılan her çağrıyla, oturum dosyası değiştirme 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, session.gc_maxlifetime parametresinin incelikleriyle 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 kullanımı bırakacağız. PHP mekanizmaları ve kullanıcıların hareketsizlik zamanını kendi başımıza kontrol etmemizi sağlayacak birkaç yeni oturum değişkeni tanıtacağız.

startSession ($ isUserActivity = true) ($ sessionLifetime = 300; if (session_id ()) return true; // Çerez ömrünü tarayıcı kapanana kadar ayarlayın (her şeyi sunucu tarafında kontrol edeceğiz) ini_set ("session.cookie_lifetime" ", 0) ; if (! session_start ()) return false; $ t = zaman (); if ($ sessionLifetime) (// Kullanıcı hareketsizlik zaman aşımı ayarlanmışsa, // son kullanıcı etkinliğinden bu yana geçen süreyi kontrol edin / / (lastactivity oturum değişkeni güncellendiğinde son isteğin zamanı) if (isset ($ _ SESSION ["lastactivity"]) && $ t - $ _ SESSION ["lastactivity"]> = $ sessionLifetime) (// son kullanıcı etkinliğinden bu yana geçen süre // daha fazla hareketsizlik zaman aşımı, 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, // lastactivity değişkenini mevcut vr'nin değeriyle güncelleyin emeny, // böylece oturum süresini başka bir oturumla uzatırÖmür boyu saniye if ($ isUserActivity) $ _SESSION ["lastactivity"] = $ t; )) true döndür; )

Özetleyelim. Her istekte, son kullanıcı etkinliğinin olduğu andan içinde bulunulan ana kadar zaman aşımına ulaşılıp ulaşılmadığını kontrol ederiz ve ulaşılırsa, FALSE döndürerek oturumu yok eder ve işlevin yürütülmesini durdururuz. Zaman aşımına ulaşılmamışsa ve TRUE değerine sahip $ isUserActivity parametresi fonksiyona geçirilmişse, son kullanıcı etkinliğinin zamanını güncelliyoruz. Tek yapmamız gereken, çağrı komut dosyasında isteğin kullanıcı etkinliğinin sonucu olup olmadığını belirlemek ve değilse, $ isUserActivity parametresinin değeri FALSE'e eşit olan startSession işlevini çağırmaktır.

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

Yorumlarda, YANLIŞ döndürmenin hatanın nedenini tam olarak anlamadığını fark ettik 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. Ama yorumlara göre açıklayacağım.

Gördüğünüz gibi, sessionStart işlevi iki durumda FALSE döndürebilir. Ya bazı nedenlerden dolayı oturum başlatılamadı dahili hatalar sunucu (örneğin, yanlış ayarlar php.ini'deki oturumlar) veya oturumun süresi doldu. İlk durumda, kullanıcıyı sunucuda sorun olduğuna dair bir hata içeren bir sayfaya ve bir desteğe başvurma şekline yönlendirmemiz gerekir. İkinci durumda, kullanıcıyı oturum açma formuna aktarmalı ve içinde oturumun sona erdiğini belirten ilgili bir mesaj göstermeliyiz. Bunun için hata kodlarını girip FALSE yerine karşılık gelen kodu döndürmemiz ve call method'da kontrol edip ona göre hareket etmemiz gerekiyor.

Şimdi, sunucudaki oturum hala mevcut olsa bile, kullanıcı hareketsizlik zaman aşımı süresi dolmuşsa, ilk erişildiğinde yok 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ı tanımlama bilgisi otomatik olarak yok 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 hareketsizliğinin 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. Ancak adil bir soru ortaya çıkıyor - zaman aşımı sona erdikten sonra şimdiye kadar yok ettiysek, eski oturumu kim yok edecek? Yoksa sonsuza kadar oturum dizininde mi kalacak? PHP'nin eski oturumları temizlemek için çöp toplama adı verilen bir mekanizması vardır. Sunucuya bir sonraki istekte başlar ve tarihe göre tüm eski oturumları temizler. son değişiklik oturum dosyaları. Ancak sunucuya yapılan her istekte çöp toplama mekanizması başlamaz. Başlatma sıklığı (daha doğrusu olasılık), 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ın başlama olasılığıdır. Bu nedenle, sunucuya yapılan her istekte oturum temizleme mekanizmasının başlaması için bu parametrelerin eşit değerlere, örneğin "1"e ayarlanması gerekir. Bu yaklaşım, oturum dizininin temiz olmasını sağlar, ancak açıkçası sunucu için çok fazla yüktür. Bu nedenle, üretim sistemlerinde session.gc_divisor varsayılan olarak 1000'e ayarlanmıştır; bu, çöp toplama motorunun 1/1000 olasılıkla başlayacağı anlamına gelir. Bu ayarları php.ini dosyanızda denerseniz, yukarıdaki durumda, tarayıcı kapandığında ve tüm çerezlerini 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 itibariyle güncelleme

Oturum dosyasının engellenmesi nedeniyle komut dosyalarının askıda 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 olarak - uzun anket).

Başlangıç ​​olarak, bu sorunun doğrudan sunucu yüküne veya kullanıcı sayısına bağlı olmadığını not ediyorum. Tabii ki, ne kadar çok istek olursa, betikler o kadar yavaş çalışır. Ancak bu dolaylı bir bağımlılıktır. Sorun yalnızca bir oturumda, sunucu bir kullanıcı adına birkaç istek aldığında ortaya çıkar (örneğin, bunlardan biri uzun ankettir 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, bir sonraki istek askıda 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şvurmanız gerektiği anlamına gelir. Ve bazı çalışma verilerini oturum değişkenlerinde saklamanız gerekiyorsa, oturumun hemen başında okuyun, daha sonra kullanmak üzere yerel değişkenlere kaydedin ve oturumu kapatın (yani, oturumu oturumu_write_close işlevini kullanarak kapatmak, kullanarak yok etmek değil). session_destroy).

Örneğimizde bu, bir oturumu açtıktan hemen sonra, oturumun ömrünü ve yetkili bir kullanıcının varlığını kontrol ettikten sonra, uygulama için gerekli tüm ek oturum değişkenlerini (varsa) okuyup kaydetmemiz, ardından oturumu session_write_close () kullanarak kapatmamız gerektiği anlamına gelir. ) uzun bir anket veya normal bir istek olsun, bir komut dosyasının yürütülmesini çağırın ve devam ettirin.

Oturumları yetkisiz kullanıma karşı koruma

Bir durum hayal edelim. Kullanıcılarınızdan biri, tarayıcı tanımlama bilgisini (oturumumuzun depolandığı) çalan ve belirtilen e-postaya gönderen bir Truva Atı takar. Saldırgan bir tanımlama bilgisi alır ve bunu yetkili kullanıcımız adına bir istekte 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, 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? 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 özgürce istek gönderebilirsiniz (doğal olarak, bu oturumun ömrü boyunca). Belki de bu en yaygın saldırı türü değildir, ancak teoride her şey oldukça mümkün görünüyor, özellikle böyle bir Truva atının kullanıcının tarayıcı çerezlerini soymak için yönetici haklarına bile ihtiyacı olmadığı düşünüldüğünde.

Bu tür saldırılara karşı nasıl savunma yapabilirsiniz? Yine, açıkçası, oturum tanımlayıcısının ömrünü sınırlayarak ve tanımlayıcıyı bir oturumda periyodik olarak değiştirerek. Ayrıca oturumun adını değiştirebilir, eskisini tamamen silip yeni bir oturum oluşturarak, 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 tanımlayıcısıyla sınırlayacağız.

Oturum tanımlayıcısının ömrü ne kadar kısa olursa, bir saldırganın bir kullanıcının isteğini oluşturmak için çerezleri almak ve kullanmak için o kadar az zaman alacağı açıktır. İdeal olarak, her istek için başka birinin oturumunu kullanma olasılığını en aza indirecek yeni bir tanımlayıcı kullanılmalıdır. Ancak, oturum kimliğini yeniden oluşturma zamanının keyfi olarak ayarlandığı genel durumu ele alacağız.

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

fonksiyon startSession ($ isUserActivity = true) (// Oturum Kimliği ömrü $ idLifetime = 60; ... if ($ idLifetime) (// Oturum kimliği yaşam süresi ayarlanmışsa, // oturumun oluşturulmasından bu yana geçen süreyi kontrol edin veya son yeniden oluşturma // (başlangıç ​​zamanı oturum değişkeni güncellendiğinde son isteğin zamanı) if (isset ($ _ SESSION ["starttime"])) (if ($ t - $ _ SESSION ["starttime"]> = $) idLifetime) (// Oturum kimliğinin süresi doldu // Yeni bir kimlik oluştur session_regenerate_id (true); $ _SESSION ["starttime"] = $ t;)) else (// Oturum yeni oluşturulduysa buraya geliriz // Ayarla geçerli zamanda oturum kimliği oluşturma zamanı $ _SESSION ["starttime"] = $ t;)) return true;)

Bu nedenle, yeni bir oturum oluştururken (kullanıcı başarıyla oturum açtığında gerçekleşir), bizim için oturum tanımlayıcısının son neslinin zamanını saklayan oturum değişkeni başlangıç ​​zamanını mevcut sunucu zamanına eşit bir değere ayarladık. Ayrıca her istekte, tanımlayıcının son neslinden bu yana yeterli sürenin (idLifetime) geçip geçmediğini kontrol ediyoruz ve geçtiyse yeni bir tane oluşturuyoruz. Böylece, 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 tanımlayıcısı, session_regenerate_id() işlevi çağrıldığında, session_start() işlevine benzer şekilde yeni bir çerez gönderen tarayıcı çerezine girer, bu nedenle çerezleri kendimiz güncellememiz gerekmez.

Oturumlarımızı olabildiğince güvenli hale getirmek istiyorsak, tanımlayıcının ömrünü bir olarak ayarlamak, hatta session_regenerate_id() işlevini parantezlerin dışına koymak ve tanımlayıcının yeniden oluşturulmasına yol açacak tüm kontrolleri kaldırmak yeterlidir. her istekte. (Bu yaklaşımın performans üzerindeki etkisini test etmedim ve yalnızca session_regenerate_id (true) işlevinin temelde yalnızca 4 eylemi gerçekleştirdiğini söyleyebilirim: yeni bir tanımlayıcı oluşturma, oturum tanımlama bilgisinden bir başlık oluşturma, eskisini silme ve yeni bir oturum dosyası oluşturma).

Lirik arasöz: Truva atının saldırgana çerez göndermeyecek kadar akıllı olduğu ortaya çıkarsa, ancak çerezin alınmasından hemen sonra önceden hazırlanmış bir sahte istek gönderilmesini organize ederse, yukarıda açıklanan yöntem büyük olasılıkla koruma sağlayamaz. böyle bir saldırıya karşı, çünkü Truva Atı'nın çerezi aldığı zaman ile sahte olanın gönderilmesi arasında, istekte pratikte hiçbir fark olmayacak ve bu noktada oturum kimliğinin yeniden oluşturulmama olasılığı yüksek.

Birkaç kullanıcı adına tek bir tarayıcıda aynı anda çalışabilme

Düşünmek istediğim son görev, birkaç kullanıcı için bir tarayıcıda aynı anda çalışma olasılığı. Bu özellik, özellikle kullanıcıların eşzamanlı çalışmalarını taklit etmeniz gerektiğinde, test aşamasında kullanışlıdır ve bunu favori tarayıcınızda yapmanız ve mevcut cephaneliğin tamamını kullanmamanız veya tarayıcının birden fazla örneğini "gizli modda açmamanız" önerilir. " modu.

Önceki örneklerimizde, oturum adını açıkça belirlemedik, bu nedenle 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 çerezler gönderdiği anlamına gelir. Açıkçası, çerezin adı her zaman aynıysa, bir tarayıcıda iki oturum düzenlemenin bir yolu yoktur. aynı isim... Ancak her kullanıcı için farklı bir oturum adı kullansaydık sorun çözülürdü. Yani yapacağız.

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

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

Çözüm

Sonuç olarak, yukarıda tartışılan tüm görevler de dahil olmak üzere PHP oturumlarıyla çalışmak için işlevlerimizin tam kodunu vereceğim.

startSession ($ isUserActivity = true, $ prefix = null) ($ sessionLifetime = 300; $ idLifetime = 60; if (session_id ()) true dönerse; session_name ("MYPROJECT". ($ Önek? "_". $ Önek: "")); ini_set ("session.cookie_lifetime", 0); if (! session_start ()) return false; $ t = zaman (); if ($ sessionLifetime) (if (isset ($ _ SESSION ["lastactivity") ] ) && $ t - $ _ SESSION ["lastactivity"]> = $ sessionLifetime) (destroySession (); return false;) else (if ($ isUserActivity) $ _SESSION ["lastactivity"] = $ t;)) if ( $ idLifetime ) (if (isset ($ _ SESSION ["starttime"])) (if ($ t - $ _ SESSION ["starttime"]> = $ idLifetime) (session_regenerate_id (true); $ _SESSION ["starttime"] = $ t; )) else ($ _SESSION ["starttime"] = $ t;)) return true;) function destroySession () (if (session_id ()) (session_unset (); setcookie (session_name (), session_id ()) , zaman () -60 * 60 * 24); session_destroy ();))

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

Nuuu, hadi çözelim.

İlk olarak, aynı wiki'de HTTP hakkında bilgi edinin. Tam olarak bilmenize gerek yok, ancak isteklerin/yanıtların yapısı hakkında asgari düzeyde bir anlayışa sahip olmalısınız, istek ve yanıtın üstbilgileri ve bir gövdesi olduğunu anlamalısınız (isteğin türüne bağlı olarak bir gövde olmayabilir / cevap).

İşte bu kadar. Kurabiye. Çerezler tarayıcı tarafında yaşar. Sunucuya her istek için HTTP başlığı tarafından iletilirler (resim aramış olsanız bile). Sadece çerezler var, sadece http çerezleri var. Çerezler, ana bilgisayar ve yola göre ayırt edilebilir. Bütün bunlar bize esneklik sağlıyor ve güvenlik konusunda yardımcı oluyor. PHP'de $ _COOKIE'nin içeriği bize bir SAPI sağlar. PHP işleme için bir istek aldığında, kullanılan SAPI (php-fpm, cgi, mod_php kendi SAPI uygulamalarına sahiptir) şu an isteğin başlıklarını ve gövdesini alır, bunları ayrıştırır ve $ _SERVER, $ _GET gibi, $ _COOKIE dahil olmak üzere tüm bu süper küresel dizileri doldurur. Müşterinin bize gönderdiği her şey (istekte bulunan şey istemcidir, bunları işleyen şey sunucudur) ve tarayıcı bize yalnızca talebin gönderildiği yere bağlı olarak mümkün olan çerezleri gönderir. Çerezler, yanıtta Set-Cookie başlığı tarafından ayarlanır, yani burada prensipte 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ırlanır, çünkü tüm bu çerezleri unutacaktır.

İşte ... seanslar ... B PHP oturumu genellikle bir dosya. Sadece rastgele bir ada sahip bir dosya. Diyelim ki php.ini'de session.autostart belirtilmişse veya session_start çağrıldıysa, kullanıcı oturumu için bir dosya oluşturulur (ihtiyaçlarınıza bağlı olarak onu redis veya memcache'ye, depolama alanınıza vb. taşıyabilirsiniz. ayrıca varsayılan olarak olan verileri de şifreleyin). Bu dosyanın bir kimliği var, sadece rastgele bir dizi. Ve istek işlenirken önceki istekten bir oturum bulunamazsa, yeni bir tane oluşturulur.

Ve şimdi en ilginç olana geliyoruz - PHP, önceki istekten geçerli olana oturumu nasıl bağlar. Ve burada her şey oldukça basit - çerezler. Bir kullanıcıya bir oturum atandığında, otomatik olarak bir salt http çerezi ayarlanır (böylece kötü insanlar oturumumuzu js'den alamazlar) oturum tanımlayıcısının yazıldığı bir çerez. Tarayıcı hata ayıklayıcısında, bir PHPSESSID çereziniz olup olmadığını (ad ayarlardan değiştirilebilir ve genel olarak, oturumlar yalnızca çerezler aracılığıyla değil, bunlar zaten güvenlik kalemleridir) oturumları denediğinizde görebilirsiniz.

SAPI tarafından bir istek işlendiğinde, session.autostart varlığında, yeni bir oturum oluşturmaya başlamadan önce, yine de oturum tanımlayıcılı bir çerezimiz olup olmadığına bakar, olup olmadığını kontrol eder ve varsa, sakinleşir ve yenisini yaratmaz. Oturum tanımlama bilgileriyle bağlı olduğundan, bu tanımlama bilgisinin ömrünü (php.ini'de) ayarlayabilir ve böylece oturumun ömrünü ayarlayabilirsiniz.

Burada ... çerezler ne zaman ve ne zaman oturumlar kullanılır? Ç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ı anlamanız önerilir. Yani, 1 kilobayt veri almak için başlıklarda birkaç kilobayt çerez aktarmamız gerektiğinde hiç hoş değil. Optimizasyona odaklanan insanlar, trafik ve paket miktarını azaltmak için (genellikle basit bir HTTP isteği bir TCP paketinin boyutuna sığar). JS'deki bu verilerle herhangi bir sayfada, örneğin çevirileri JS'de de uygulamak için kullanıcı tarafından seçilen yerel ayarda çalışmanız gerekiyorsa, çerezleri kullanmalısınız. Diğer her şey için, elbette, oturumları kullanmak en iyisidir. Her durumda, ilk aşamalarda, çok karmaşık bir şey yapmak zorunda kalmayacaksınız.

HTTP, durum bilgisi olmayan bir istek protokolüdür. Bu, kullanıcının bir istek gönderdiği anlamına gelir, sunucu bu isteğe daha sonra hatırlamadan yanıt verir. izlemek için önemli bilgi(örn. kullanıcı tercihleri, kullanıcı eylemleri vb.) web sitesinde ne zaman PHP yardımıçerezler, iyi veya çerezler oluşturulur. Bu yazımda çerezlerle nasıl çalışılacağı, nasıl oluşturulmaları gerektiği, hangi parametrelere sahip oldukları ve bunları nasıl silebileceğinizden bahsedeceğim.

Çerez nedir?

Çerezler, bilgileri doğrudan kullanıcının tarayıcısında saklamak için çok kullanışlıdır. Basit Metin dosyası maksimum 4 kb veri depolar.

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

Çerezler genellikle oturum açma bilgilerini, parolaları ve daha fazlasını depolar. Örneğin, siteye gidiyorsunuz, kullanıcı adınızı ve şifrenizi girin. Site, bu verilerle sizin için otomatik olarak bir çerez oluşturur. Ve siteyi bir sonraki ziyaretinizde, sadece çerezlerin varlığını kontrol eder ve bunlara kaydedilen kullanıcının verilerini yükler.

// Böyle bir site için bir dizin sayfası örneği if ($ _ COOKIE ["login"]) (header ("location: /lk/index.php?login=".$_COOKIE ["login" ]); / / Doğrudan kişisel hesabınıza transferler ) // Ardından, örneğin, giriş ve kayıt formu gelir

Neden Çerez?

HTTP durum bilgisi olmayan bir protokoldür, bu nedenle kullanıcının sitedeki önceki eylemlerini izlemenin bir yolu yoktur. Çerez "ler en iyi yol veri depolama için. Kırdığın arzuların kurabiyeleri ve gelecekte başına gelebileceklerin olduğu bir kağıt parçası hakkında her şeyi biliyorum. Bana gelince, bacaklar buradan isim hakkında büyüyor.

PHP Çerezleri

Aslında, ne olduğunu zaten açıkladığım için, PHP'de çerezlerin nasıl ayarlanacağını öğrenelim.

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

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

Setcookie (ad, değer, zaman, yol, alan, güvenli);

isim - Çerezin adını belirtir.

val - Çerezde saklamak istediğimiz değer. Bir tanımlama bilgisi her zaman bir dizgenin değerini depolar.

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

etki alanı (isteğe bağlı) - Çerezin kullanılabilir olduğu etki alanını ayarlayın. Birden fazla alt alan için tanımlama bilgileri ayarlamak istiyorsanız, önek olarak noktalı ana alan adını kullanın.

Örneğin:

my.com'un tech.my.com, only.my.com gibi birden çok alt alanı olmasına izin verin. Ve my.com'da ayarlanan çerezin tüm alt alanlarım için kullanılabilir olmasını istiyorum, ardından alan adını .my.com olarak ayarladım.

güvenli (isteğe bağlı) - Bu, tanımlama bilgisinin güvenli bir HTTPS bağlantısı üzerinden iletilmesi gerekip gerekmediğini belirler. Varsayılan YANLIŞ'tır. Bu doğru olarak ayarlanırsa, çerezin yalnızca güvenli bir bağlantı varsa kurulacağı anlamına gelir ve HTTP sırasında oluşturulmaması mantıklıdır.

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

Yukarıdaki betiği kullanarak login adında ve valera123 değerine sahip bir çerez oluşturacağız.

Not: Tanımlama bilgileri yalnızca dize değerlerini saklayabilir. Dizi depolayamazlar. Çerezlerde bir diziyi saklamak için önce onları bir dizgeye dönüştürmeniz gerekir. Bundan kesinlikle daha sonra bahsedeceğim.

Not: Fark ettiğiniz gibi çerezimizin kullanım süresini belirlemedim. Bu yüzden tarayıcımız kapatıldıktan sonra kaybolacak...

Çerezimiz SetCookie() yöntemi kullanılarak ayarlanacaktır. Komut dosyanız belirtilen yöntemle çalıştırıldıktan sonra, chrome'daki geliştirici panelinde veya firefox'taki firebug'daki cookie'yi kolayca kontrol edebilirsiniz.


Çerez için bir sona erme süresi tanımlamadık. 30 gün verelim. Bu durumda zamandan bahsetmemiz gerekir. Bundan sonra, kullanıcı manuel olarak silene kadar 30 gün yaşayacak.

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

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

Alt alanlar için çerezler nasıl ayarlanır?

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

Aslında bu örnek zaten verilmiş.

PHP'de bir çerezin değeri nasıl elde edilir

$ _COOKIE - Bir tanımlama bilgisinin değerini almak için kullanılır. Aşağıda, daha önce çerez setinin değerini tam olarak nasıl alabileceğinizin kodu verilmiştir.

$ val = $ _COOKIE ["giriş"]; yankı $ değer; // valera123 çıktısı verecek

PHP'de çerezler nasıl kaldırılır

PHP'de çerezleri kaldırmak için negatif bir süre (geçen süre) ayarlayın.

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

Peki eksi bir zaman belirlersek ne olur? Bu durumda, çerez otomatik olarak sona erecektir.

Çerezler hakkında önemli noktalar

1. Cook, maksimum 4 KB veri depolayabilir.

2. Yalnızca dizeleri saklayabilir.

3. Çerezlere yalnızca onları ayarlayan tarayıcı tarafından erişilebilir. Çerezler ayarlandı Chrome tarayıcı içinde mevcut olmayabilir Mozilla tarayıcısı, veya başka bir şey.

4. Çerezlerde gizli ve çok hassas verileri saklamaktan kaçının.

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

PHP değişkenlerinin çalışma süresi $ _SESSION ve sonuç olarak web uygulamalarının etkinliği, oturumun süresine bağlıdır. Örneğin sistemde bir kullanıcı yetkilendirilmişse, kullanıcı adı ve şifresini tekrar girmek zorunda kalmadan boşta kalabileceği süre bu parametreye bağlıdır.

var Farklı yollar oturum ömrünü ayarlama. Bir örnekle anlamaya çalışalım işletim sistemi Linux.

Oturum ömrü nasıl bulunur

kurmadan önce bakmakta fayda var Şu anki durum... Bunu yapmanın birkaç yöntemi vardır:

1. php komutu ile 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ğerlerdir. cookie_lifetime => 0 tarayıcı kapanana kadar çerezlerin eylemini belirtir, bu parametreyi belirli bir değere ayarlarsanız, oturum aktifken oturum kesintiye uğrayacaktır, bu nedenle sıfırda bırakmak daha iyidir.

2. ini_get php işlevini kullanma

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

Yankı $ maxlifetime;
echo $ cookielifetime;

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

* systemd olmayan Linux sürümlerinde komutu kullanın servis apache2 yeniden başlatma veya hizmet httpd yeniden başlat.

FastCGI (PHP-FPM) kullanırsak:

.htaccess dosyası aracılığıyla özelleştirme

Bu dosya, web yöneticisinin bazı web sunucusu ayarlarını yönetmesini sağlar. 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. Bununla birlikte, bir yol da var (aşağıda bununla ilgili).

.htaccess dosyasına şunu ekleyin:

php_value session.gc_maxlifetime 86400
php_value session.cookie_lifetime 0

* gördüğünüz gibi, parametreler php.ini üzerinden yapılandırma yaparkenki ile aynıdır.

Yukarıda belirtildiği gibi, Apache kullanılmadığı sürece bu yöntem çalışmayacaktır. Ancak yapılandırma 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_değeri = 86400
php_değeri = 0

Hizmeti yeniden başlattıktan sonra:

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 olması gerektiğinde yararlı olabilir. farklı zaman yaşam seansı. Bunu yapmak için ini_set ve session_set_cookie_params PHP 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ıç();

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 program parametrelerinde oturum ömrünü ayarlamak gerekir. Her uygulamanın, kendi başınıza çözmeniz gereken kendi ayarları vardır. Örneğin, CMS Bitrix'te bir oturum ayarlamayı verelim.

git Kullanıcı grupları- bir grup seçin - Güvenlik... "Oturum ömrü (dakika)" parametresini bulun ve süreyi ayarlayın, örneğin 1440 (dakika olarak 24 saat).

Oturumlar otomatik olarak nasıl yenilenir?

Seans belirli bir süre için düzenlenmişse ve kesin zaman, bu aktif kullanıcı oturumunu kesintiye uğratabilir. Ziyaretçinin sayfayı yenilemesi durumunda oturum süresinin otomatik olarak uzatılması çok daha uygundur. Bunun için yukarıdaki tüm örneklerde 0 olarak ayarladığımız cookie_lifetime parametresi var.

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

Oturumu kontrol etmek ve kesmek gerekirse, php işlevini kullanabilirsiniz. session_destroy ().

Oturum dosyası depolama yolu

Oturum dosyaları için depolama konumu parametre tarafından belirlenir. session.save_path ayrıca yaşam süresi de öyle. Varsayılan olarak, yol kullanılabilir / var / lib / php / oturumlar.

o önemli parametre- web sunucusunun bu dizine yazma izinlerine sahip olmaması, oturumların saklanmasının imkansızlığına yol açacak ve bu da beklenmeyen uygulama sonuçlarına neden olacaktır.

Web sunucusu, istemciyle kalıcı bir bağlantı sağlamaz ve her istek, öncekilerle herhangi bir bağlantı olmaksızın yeni bir istek gibi değerlendirilir.
Yani, aynı ziyaretçiden gelen istekleri takip edemez veya 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 bir ş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 duyulan ihtiyacı ayrıntılı olarak açıklamayacağım. Bunlar, bir e-mağazadaki alışveriş sepeti, yetkilendirme ve örneğin sitenin etkileşimli bölümlerini spam'den korumak gibi tamamen önemsiz olmayan problemler gibi ders kitabı durumlarıdır.

Prensipte, yerleşik PHP kadar işlevsel değil, özünde benzer olan kendi oturum analogunuzu yapmak oldukça kolaydır. Çerezler ve veritabanı hakkında.
Bir komut dosyası talep ederken, belirli bir adla bir çerez gelip gelmediğine bakarız. Çerez yoksa, onu ayarlayın ve veritabanına kullanıcı verileriyle yeni bir satır yazın. Bir çerez varsa, veritabanından okuruz. Bir istekle daha 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ı kullanmayı tercih eden bazı nüanslar vardır.

Yalnızca ilki etkinleştirilirse, oturumun başında (her aramada oturum_başlangıç ​​()) istemci için bir çerez kurulur. Tarayıcı, sonraki her istekte bu tanımlama bilgisini doğru bir ş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 PHP her zaman bir tanımlayıcıya sahip çerezler almadan yeni bir oturum başlatır ve mekanizma çalışmaz.

Yalnızca ikincisi etkinleştirilirse, çerez ayarlanmaz. Ve olan şey, bunun uğruna, aslında, aslında, yerleşik oturum mekanizmasını kullanmaya değer. Komut dosyası işini yaptıktan ve sayfa tamamen oluşturulduktan sonra, PHP hepsine bakar ve her bağlantıya ve her forma bir oturum kimliği ekler. Şuna 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, istekte ihtiyacımız olan değişkeni - oturum tanımlayıcısını gönderir!
Açık nedenlerle, kimlik yalnızca göreli bağlantılara eklenir.

Teorik olarak, çerezler ve bir veritabanı ile ilgili ev yapımı oturumlarımızda, tüm bağlantılara kimliğin aktarımını manuel olarak atayabilirsiniz - ve daha sonra kendi oturumlarımız çerezlerden bağımsız olarak çalışacaktır. Ama görüyorsun, bu işi başka biri yaptığında daha hoş oluyor? ;-)

Her iki seçenek de PHP'nin son sürümlerinde varsayılan olarak etkindir. PHP bunu nasıl hallediyor? Aşçı her zaman sergilenir. Ve bağlantılar, yalnızca PHP oturum kimliğine sahip bir tanımlama bilgisi bulamazsa otomatik olarak tamamlanır. Bir kullanıcı bu oturum sırasında siteyi ilk kez ziyaret ettiğinde, bir çerez alır ve bağlantılar eklenir. Bir sonraki istekte, çerezler destekleniyorsa, PHP çerezi görür ve bağlantıları tamamlamayı durdurur. Çerezler çalışmazsa, PHP bağlantılara düzgün bir şekilde kimlik eklemeye devam eder ve oturum kaybolmaz.
Çerezleri çalıştıran kullanıcılar, id ile uzun bağlantıyı yalnızca bir kez göreceklerdir.

Füh. Tanımlayıcının aktarımı tamamlandı.
Artık geriye, sunucu tarafında veri bulunan bir dosyayı bağlamak kalıyor.
PHP bunu bizim için yapacak. sadece yazman yeterli
oturum_başlangıç();
$ _SESSION ["test"] = "Merhaba dünya!" ;

PHP, test değişkenini bu oturumla ilişkili dosyaya yazacaktır.
Burada çok önemli bir nokta var.
Dizi $ _SESSION- özel.
İçinde, aslında, çeşitli komut dosyalarında kullanıma sunmak 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şvurmak yeterlidir. Aşağıda bir örnek olacak.

Çöp toplama - eski olanı kaldırma PHP dosyaları ayrıca kendim yapıyor. Veri kodlama ve bir dizi başka gerekli şeyin yanı sıra. Bu bakımın sonucu olarak seanslarla çalışmak oldukça kolaydır.
İşte aslında buradayız ve seansların çalışması örneğine geliyoruz.
Örnek çok küçük:
oturum_başlangıç();

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

Oturumda bir sayaç değişkenimiz olup olmadığını kontrol ediyoruz, yoksa 0 değeri ile oluşturup değerini çıktı alıp bir artırıyoruz. 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 oturuma ihtiyacımız olan HER dosyanın en başına SADECE BİR (!) Satır yazmanız gerekir:
oturum_başlangıç();
Ardından $ _SESSION dizisinin öğelerine bakın. Ö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 varsa, yazmanız yeterlidir
unset ($ _ SESSION ["var"]);
O zaman değilse yakında 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önderilemiyor - üstbilgiler zaten gönderildi
Uyarı: Oturum önbellek sınırlayıcısı gönderilemiyor - üstbilgiler zaten gönderildi

Aynı nedenden dolayı çözüm bu olguda anlatılmaktadır.
Üçüncü,
Uyarı: open (/ tmp \ sess_SID, O_RDWR) başarısız oldu: Satır numarasında full_script_path içinde böyle bir dosya veya dizin (2) yok(önceden benziyordu 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 yol, oturum dosyalarının yazıldığı dizine 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 = 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) ilk ikisine yol açacaktır, çünkü hata mesajı tarayıcıya gönderilir ve ondan sonra başlıkları kullanamazsınız. Bu nedenle, erken bir sonuç aramak için acele etmeyin, önce doğru yolu yazın!

Oturumlarla uğraşırken bir sonraki en yaygın sorun, register_globals'ın ağır mirasıdır. Komut dosyası değişkenlerine $ _SESSION dizisinin dizinleriyle aynı adları VERMEYİN!
register_globals = on ile değerler birbirinin üzerine yazar ve kafanız karışır.
Ve register_globals = kapalıysa, başka bir hata belirir: "Komut dosyanız muhtemelen PHP 4.2.3'e kadar var olan bir oturum yan etkisine dayanıyor." ... Ondan 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 indeksleriyle eşleşen global değişken isimleri vermemelisiniz.

Çalışmıyorsa, ancak hiçbir mesaj görüntülenmiyorsa, 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 onlara.
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 yüzden 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 yoluyla kimliğin transferini etkinleştirmemesi mümkündür, ve çerezler nedense çalışmıyor.
Çerezlerle neler olduğunu görün.
Genel olarak, oturumlarınız "çalışmıyorsa", önce oturum tanımlayıcısını elle aktarmayı 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 Zamanlar.

Güncelleme ";
?>

Bunu yaparken, session.use_only_cookies yönergesinin etkinleştirilmediğinden emin olun; bu, PHP'nin bir URL üzerinden geçirilmişse bir oturum kimliğini kabul etmesini engeller.

Bu örnek işe yaramazsa, sorun ya banaldadır. 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 çerezlerdedir. Tarayıcının onu döndürüp döndürmediğine bakılmaksızın, sunucunun tarayıcıya ne tür bir tanımlama bilgisi koyduğunu izleyin. Tarayıcı ve sunucu arasındaki HTTP başlık değiş tokuşlarına bakarken arama yapmak çok yararlıdır.
Çerezlerin 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 birlikte gönderdiğinden ve tarayıcının geri döndüğünden emin olun. Ve tanımlayıcılar birbiriyle çakışırken =)
Çerezin ayarlanması şöyle görünmelidir
Set-Çerez: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6;
veya nasıl
Set-Çerez: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; yol = /
(kök dizinden olmayan bir komut dosyası istiyorsanız)
Sunucu yanıtı gibi görünmelidir
Tanımlama bilgisi: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6
veya
Tanımlama bilgisi: PHPSESSID = prlgdfbvlg5fbsbshch6hj0cq6; b = 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 ada sahip olduğundan (en az bir nokta içeren ve alt çizgi gibi yasaklı karakterleri içermeyen) emin olun ve tarayıcı önbelleğinizi 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ğinize bakın, buradaki örneği adım adım aktarın, betiğinizde hata ayıklayın.

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

Ayrıca, çok nadirdir ve sorunun nereden geldiği tamamen belirsizdir, sorun session.save_handler ayarının dosyalardan başka bir değere sahip olmasıdır. Durum böyle değilse, düzeltin.

Güvenlik
Oturum güvenliği geniş bir konudur. Bu nedenle, birkaç ana noktaya odaklanacağım.
En ders kitabı şey, tanımlayıcıyı geçmemek 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 = 0'ın yanı sıra session.use_only_cookies = 1'i de unutmayın.
Oturumu bir IP adresine bağlamanız tavsiye edilir: bu şekilde, tanımlayıcı çalınırsa, kötü adam çoğu durumda onu kullanamaz.
Oturum dosyalarını kaydetmek için kendi dizininizi ayarlayabileceğiniz session.save_path yönergesini kullanmanız önerilir. Bu, sunucunun varsayılan paylaşılan geçici dizininde depolanmalarından daha güvenlidir.

Ek bilgi:

  • Oturum mekanizması, tanımlama bilgilerine ek olarak, 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 dosyayı indirmeyi reddediyor. Bu başlıktan dolayıdır. Telefon etmek
    session_cache_limiter ("özel");
    oturuma başlamadan önce sorunu çözmelidir.
  • İşin garibi, ama dizide $ _SESSION sayısal indeksleri kullanamazsınız - $ _SESSION [1], $ _SESSION ["10"]- oturumlar çalışmayacak.
  • 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 tekrar mümkün.
  • 4.3.3 sürümünden önce, PHP tanımlama bilgisi, yalnızca istek oturumun başlangıcında bir tanımlayıcı içermiyorsa tanımlama bilgisini gönderirdi. Artık her aramada çerez gönderiliyor oturum_başlangıç ​​()

    Oturumları kullanarak yetkilendirme örneği
    Yukarıdakilerin hepsini küçük bir örnekle açıklayalım:
    auth.php dosyasını oluşturalım:
    if (isset ($ _ POST ["auth_name"]))
    {
    $sql = "SEÇ * KULLANICILARDAN NEREDE isim =? S";
    $ satır = $ db -> getRow ($ sql, $ _POST ["auth_name"]);
    if ($ satır && password_verify ($ _POST ["auth_pass"], $ satır ["geçer"])) (
    $ _SESSION ["user_id"] = $ satır ["id"];
    }
    başlık ("Yer: http://". $ _SERVER ["HTTP_HOST"]. $ _SERVER ["REQUEST_URI"]);
    çıkış;
    }

    if (isset ($ _ GET ["eylem"]) AND $ _GET ["eylem"] == "çıkış") (
    oturum_başlangıç();
    session_destroy();
    başlık ("Yer: http://". $ _SERVER ["HTTP_HOST"]. "/");
    çıkış;
    }

    if (! isset ($ _ SESSION ["user_id"])) (
    ?>








    çıkış;
    }

    Artık tüm korumalı komut dosyalarına satırı yazmak yeterlidir.
    "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 bağlantının oluşturulduğu varsayılmaktadır. Ayrıca, önerilen password_hash işlevi kullanılarak parolanın özetlendiğini varsayar.
    Korumalı dosya örneği:

    oturum_başlangıç();
    "safemysql.class.php" içerir;
    $ db = new safemysql (["db" => "test"]);
    "auth.php" içerir;
    ?>
    gizli

    çıkış Yap

    Operasyon! Çok Faydalı Linkler:
    http://www.php.net/manual/ru/ref.session.php - resmi belgelerde PHP'de oturum desteği hakkında en yeni ve güncel bilgiler ve ayrıca çok sayıda kullanıcı yorumu. Okumanız şiddetle 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 çevirisi.
    http://phpclub.ru/detail/article/sessions
    "Seanslar Hakkındaki Gerçek" başlıklı iddialı bir makale. İkircikli bir izlenim bırakıyor. Yazar başlangıçta oturum mekanizmasından ÇOK kolay bahsediyor, ancak makalenin sonuna doğru önerdiği yöntemler tamamen çamurlu.

    Siteden Dmitry Borodin tarafından ders kitabı makalesi
    http://php.spb.ru/ kesinlikle TAVSİYE EDİLMEZ.
    Beyler, o çok demode. İçinde sadece olgusal yanlışlıklar olmakla kalmıyor, aynı zamanda PHP'deki oturumlar uzun süredir kullanılmamaktadır.
    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 ne yazık ki internette dolaşan ve yıllardır güncellenmeyen birçok yazı da güncelliğini yitirmiş durumda.