İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır

PHP ile Oturum Yönetimi (Session Management)

HTTP protokolünün o anki durumu kaydetmeyen (stateless) yapısı web uygulamaları için en önemli sorunu oluşturmuş ve bunun aşılabilmesi için hem sunucu, hem de istemci tarafında çeşitli metodlar geliştirilmiştir.

Web sunucusuna bağlanan bir kişi web tarayıcısı aracılığıyla sunucudan bir URL adresi ile belirtilmiş kaynağı ister (HTTP request) ve sunucu da istemi değerlendirir ve sunucu tarafında yapılması gerekenleri yaparak tarayıcıya cevabını iletir (HTTP response). Arada sürekli bir TCP/IP bağlantısı yoktur. Aslında kaynak kullanımı ve bant genişliği açısından oldukça avantajlı olan bu durum web uygulaması geliştirirken dezavantaja dönüşür. Bir web uygulamasında web sunucusuna çeşitli istemlerde bulunan kişi, bu istemleri arasında o an hangi aşamaya gelmişse oraya kadar yaptığı işlemlerin kaybedilmemesini, sunucu tarafından hatırlanmasını isteyecektir. Bu sorun sunucu tarafta oturum yönetimi (session management) kavramının doğmasına sebep olmuştır.

Web üzerinde oturum yönetimi sunucu ve istemci tarafta olmak üzere ikiye ayrılabilir:

İstemci tarafta oturum yönetimi:

İstemci tarafta oturum yönetimi kavramını, bir HTTP oturumu esnasında istemci tarafa bir önceki oturuma ilişkin bilgiler atmak veya istemci taraftan bir önceki oturuma ilişkin bilgileri almak şeklinde düşünülebilir.

Eğer HTML'in form olanağından yararlanılıyorsa HIDDEN türü alanlar kullanılarak bir önceki oturum bilgisinin istemciye aktarılması ve tekrar form aracılığı ile sunucuya geri iletilmesi sağlanabilir. Uygulamanız formlardan oluşuyor ise oldukça kullanışlıdır.

Bir başka metod oturum bilgilerini URL içine gömme metodudur. Form kullanılmasına gerek kalmadan HTML linkleri içine GET metodu çağrılarının yaptığı gibi gömerek uygulama ekranları arasında bilgi taşınabilir.

Son olarak cookie'ler kullanılabilir. Cookie'lerin çalışma mantığı basittir. Browser web sunucusuna istemde bulunurken gönderdiği header bilgisinin arkasına daha önceden ilgili sunucunun set ettiği cookie değişkenleri ve bunların değerlerini gönderir. Sunucu bu bilgileri değerlendirerek en son nerede kalındığını hatırlayabilir. Daha sonra sunucu, browsere cevap gönderirken set etmek istediği cookie değişkenlerini ve değerlerini cevap iletisinin header kısmına koyar ve browser yoksa yeni cookie değişkenleri yaratır ya da varsa önceki cookie değişkenlerinin üstüne yazar.

Cookie'ler isim, değer, zaman aşımı süresi, kaynak sunucu domain adresi ve istenen URI path bilgisi gibi alanlar içerebilirler.

İstemcilere cookie göndermek için setcookie fonksiyonu kullanılir.

İstemcilerden gelen cookieler ise $HTTP_COOKIE_VARS global associative array'inden cookie adı index olarak verilerek okunabilir.

Cookieleri sisteminizde tanımlı kullanıcıları ayırdetmekte kullanabilirsiniz. LDAP sunucusu bağlantısı için kullanıcı adı ve şifresini tekrar tekrar girmemesini sağlamak için ilk olarak login ekranını gönderen script içinde komutları ile browserlerindeki user ve pwd cookieleri temizleniyor:

setcookie("user");
setcookie("pwd");

Sonra formdan girilen değerler ikinci bir scriptde browsere set edilir:

setcookie("user", $user);
setcookie("pwd" , $pwd);

Doğrulamanın yapılacağı scriptte bu değerler alınıyor:

$user = $HTTP_COOKIE_VARS["user"];
$pwd = $HTTP_COOKIE_VARS["pwd"];

Bu metod çalışmakla birlikte yalnızca güvenli olduğunu düşündüğünüz bir bölgede kullanılmalıdır. Aksi taktirde HTTP üzerinden açık bir şekilde giden kullanıcı adı ve şifresi rahatça alınabilir. Bu nedenle authentication gereken web bölgeleri ve uygulamaları için secure socket layer kullanılması (HTTPS protokolü üzerinden) önerilir.

Setcookie fonksiyonu zaman aşımı süresi vermeden kullanılırsa cookie ömrü web tarayıcısının ömrü ile sınırlıdır (browser tarafından cache edilir). Zaman aşımı süresi verilirse cookie bilgisi dosyaya yazılır ve browser kapatılsa da zaman aşımı süresi dolana kadar silinmez.

Cookielerinizin başka domainler ve hatta URI'ler tarafından çekilebilmesini engellemek için domain name ve path parametreleri de kullanılabilir.

Ayrıca setcookie fonksiyonuyla sadece HTTPS kullanılıyorsa cookie gönderilmesi sağlanabilir.

Tüm bu metodlarda oturum verisini taşırken HTML'e özgü karakterleri HTML yorumlayıcısının ihmal etmesini sağlamak amacıyla HTTP entitylerine otomatik çevirme veya URL encoding-decoding işlemleri yapmak gerekebilir. Cookie'ler gönderilip alınırken encoding-decoding işlemleri otomatik yapılır. Ayrıca serialize ve unserialize fonksiyonları kullanalarak programınız içindeki karmaşık veri yapısında tuttuğunuz değişkenleri byte dizisi haline getirip istemci tarafa atmak ve alıp tekrar orjinal haline çevirmek çok kolaydır.

Sunucu tarafta oturum yönetimi:

NSEnterprise Server'deki session objectlerini karşılayacak yapılar shared memory ve semafor kullanılarak kurulabilir. Hafızada script ömrüyle sınırlı olmayan alanlar ayırmak için shared memory fonksiyonları kullanılabilir. Aynı scriptin hafızadaki tüm kopyalarının okuyabileceği paylaşılabilir bir alan yaratılır:

define(_SHMKEY,1000);  // Kendi atadığımız bir değer. Biricik olmalı
define(_SHMSIZE,1000); // 1000 Bytelık bir alan
define(_SHMPERM,0600); // Yalnızca web sunucunun uid'sine
                       // sahip kullanıcı okuyup yazabilsin
$shm_id = shm_attach(_SHMKEY,_SHMSIZE,_SHMPERM);

Artık shared memoy'mizden okumak için:

$value = shm_get_var($shm_id, $index);

Shared memory'e yazmak için:

shm_put_var($shm_id, $index, $value);

kullanılabilir. Burada '$index' tamsayı olmak zorudadır. Fakat shared memor'ye bu şekilde erişmek güvenli olamayacağı için semafor kullanımı şarttır:

define(_SEMKEY,999);   // Kendi atadığımız bir değer. Biricik olmalı
define(_SEMPERM,0600); // Yalnızca web sunucunun uid'sine
                       // sahip kullanıcı bu semaforu kullanabilsin
$sem_id = sem_get(_SEMKEY, 1, _SEMPERM);

Şimdi shared memory işlemlerinin yapılacağı kritik kesim semafor işleçleri arasına alınarak sözkonusu hafıza bölgesi güvenli bir şekilde kullanılabilir:

sem_acquire($sem_id); //--- Semafor aynı scriptin başka bir kopyası
                      //--- tarafından alınmışsa burada bekler

{ Kritik kesim }

sem_release($sem_id);

Burada dikkat edilmesi gereken nokta web sunucunun uid'i ile çalışan herhangibir görevin shared memory alanına erişebileceği riskidir.

Hibrit Yaklaşım ve PHP Session Desteği:

Oturum yönetiminde hem sunucu, hem de istemci tarafı bir arada kullanmak gerekebilir. Dış dünyaya açık bir sistemde bağlanan tüm kullanıcıları sistemin o an biricik bir kullanıcı olarak tanıması ve izleyen oturumlarda da bu kullanıcıyı hatırlaması istenebilir. Aynı şekilde kullanıcı doğrulaması için gerekli bilgilerin istemci tarafa aktarımının riskli olduğu açıktır. Bu sorunları aşabilmek için kullanıcılara biricik tanımlayıcılar atanarak, istemci tarafa sadece id aktarımı yaparak, verilerin yüklü bir kısmını bu id'lerle erişilebilir şekilde sunucu tarafta tutmak tercih edilir.

Burada kritik nokta farklı kullanıcıları birbirinden ayırmak için biricikliği sağlamak ve bu ID'leri tahmin edilemez şekilde üretmektir.

$ID=uniqid(getenv("REMOTE_HOST"));
setcookie("id",$ID,time()+3600,"/",".ulakbim.gov.tr");

Yukarıdaki kısım çalıştırılarak kullanıcı tarayıcısına biricik bir ID atanarak bu ID'ye ait oturum verilerinin geçici dosya, shared memory ve veri tabanında tutulması sağlanabilir.

Bir kez kulanıcı doğrulaması yapıldıktan sonra böyle bir cookie kullanılarak kullanıcı adı ve şifresi aktarılmadan sadece üretilen biricik ID değeri (token) aktarılarak doğrulamalara devam etmek mantıklı olacaktır. Burada token'in tahmin edilemeyecek ve çakışma olmayacak bir şekilde üretilmesi önem taşır. Bu amaçla md5 digestleri üretmek de tercih edilebilir.

PHP'nin 4.0 versiyonuyla gelen session desteği, cookie veya URL'e gömerek session ID'si aktarımı ve sunucu tarafta oturum verilerinin tutulması mantığını programcıya saydam hale getiriyor.

session_start fonksiyonu, istemci taraf için, yok ise bir session ID yaratarak cookie olarak set eder.

session_register fonksiyonu, başlatılan oturum için değişkenler üretir. Aşağıdaki kod değişkeninizin oturumlar arasında sürekli artmasını sağlıyor:

session_start();
session_register($count);

if(!isset($count) || !isset($var1))
  $count=0;
else
  $count++;

echo $count;

PHP geliştiriciler arasında popüler olan PHPLIB base library gelişmiş oturum yönetimi desteği sağlamaktadır.

İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır