A session magyarul munkamenet. Arra szolgál, hogy a szerveren biztonságosan lehessen a böngésző és a webalkalmazás kapcsolatának állapotát írják le. Ez azt jelenti, hogy egy webalkalmazással végzett műveleteket az alkalmazás lementi a szerveren és a következő oldallekérésekor a korábban lementett adatokat visszatölti a következő oldal hívásakor. Ezt a fajta kapcsolatot állapottartó kapcsolatnak hívjuk.
Eredetileg a cookie-k voltak hivatva ezt a feladatot ellátni, de azokat a böngészőben tároljuk, ami a biztonságot nem szolgálja, továbbá a cookie mérete legfeljebb 4 kbyte lehet.
Jellemzői
A szerveren lementett adatok biztonságban vannak, hiszen a böngésző nem éri el azokat közvetlenül, csak a webalkalmazás kódján keresztül ellenőrzött körülmények között
A szerveren tárolt adatok mérete (szinte) korlátlan, ugyanakkor minél nagyobb a munkamenettel tárolt adatmennyiség, annál lassabb lesz a következő oldal letöltés ideje, hiszen az adatokat a szerver oldalon be kell tölteni.
A munkamenetek "lejárnak", azaz ha a böngésző nem folytatja a munkát a webalkalmazással, akkor a szerveren előre beállított idő múlva érvénytelen lesz a munkamenet és az elmentett adatok elérhetetlenné válnak.
A böngésző oldalon csak a session azonosítóját tárolja a webalkalmazás, amely egy véletlenszerűen generált karatersorozat, ilyen módon nem kitalálható.
Ha a session lejárt hiába van meg a böngészőben a session azonosító, a session a továbbiakban már nem elérhető.
Milyen adatokat tároljunk?
Tipikusan olyan adatokat érdemes tárolni, amelyek a felhasználó webalkalmazással végzett tevékenységét rögzítik.
- Ilyen például bejelentkezés után az aktuális felhasználó neve, és a bejelentkezett állapot maga. Amikor kijelentkezik, akkor ezt az állapotot töröljük vagy hamisra állítjuk.
- Például egy webáruház esetén a kosár tartalma.
- Egy több oldalas űrlap kitöltése során az addig kitöltött adatok.
- Egy több oldalas listán azt, hogy éppen melyik oldalt töltöttük le.
Nem szokás olyan adatokat sessionben tárolni, amelyek a szerver oldalon egy adatbázisból kinyerhetők
Működése
Amikor a böngésző először hívja meg egy webalkalmazás valamelyik oldalát, akkor a szerver oldalon az alkalmazás ellenőrzi, hogy létezik-e a böngészőhöz tartozó session. Ha nincsen, akkor létrehoz egyet, aminek véletlenszerű nevet ad, például. 5463721fga45ba4.
Az alkalmazás lefutása során, de bármilyen egyéb kimenet létrehozása előtt elküld egy session cookie-t a böngészőnek, a fenti név felhasználásával, amit az letárol: sess_5463721fga45ba4. ez a cookie semmi mást nem tartalmaz, mint ezt az azonosítót, tovább azt, hogy a cookie mikor jár le. Minden egyes oldallekéréskor a cookie lejárati ideje meghosszabbodik
A szerver oldalon az alkalmazás kódjának lefutása közben létrejönnek a megfelelő adatok, amelyeket a kódnak be kell tenni a $_SESSION tömb megfelelő elemébe. Például: $_SESSION["logged_in"] = True;
Többféle adatot, akár egy Objektum pillanatnyi állapotát is le lehet menteni a $_SESSION tömbbe.
Amikor az oldal lefut, a szerver az adatokat serializálja, azaz olyan karaktersorozattá alakítja, amely megadott rendben tárolja string formájában az adatokat. A letárolt adatok az alábbiak: Az eltárolt változó neve, típusa, értéke. Ha a változó egy tömb, akkor a tömb elemeinek száma is. Majd a serializált adatokat a PHP motor a beállításaiban megadott könyvtárba menti egy fájlba, amelynek a neve: sess_5463721fga45ba4. Ez a könyvtár és persze a tartalma nem elérhető az internet felől, csak a PHP motor éri el.
A következő oldalletöltésnél a böngésző elküldi a szervernek a session cookie-t, ha az még nem járt le. A PHP megkeresi a szerveren a session cookie tartalma alapján a session fájlt és betölti a memóriába a $_SESSION tömbbe. Az alkalmazás tudja használni a session adatokat, módosíthatja azokat, majd az oldal lefutásával már az új adatokat menti le a szerveren.
Néhány tudnivaló
Ha a session cookie a böngészőben lejárt, akkor a böngésző nem küldi el a szervernek, tehát a session nem érhető el.
Ha a PHP-ban beállított idő eltelik, akkor a session már nem érhető el még akkor sem, ha esetleg a böngészőben a session cookie tartalmát, lejárati idejét módosítják. A session lejártát úgy állapítja meg a szerver, hogy a session fájl utolsó módosítását nézi meg. Ha azóta eltelt egy bizonyos idő, akkor a sesson érvénytelen lesz.
A session cookie lejárati ideje alapértelmezésben 1440 másodperc, amely 24 perc.Ha eddig nem kéri le újból a böngésző az adatokat, akkor a session lejár.
Még sessionben sem szabad tárolni jelszót elkódolatlanul! Csak a belépett állapotot szokás tárolni.
Alapesetben a session fájlokat a fájlrendszerben tárolja a szerver, de a webalkalmazások létrehozhatnak saját session tárolási rendszert, amely például adatbázisban tárolja a sessionöket. Ehhez csak néhány függvényt kell megalkotni és megadni a PHP-nak, hogy ez az új tárolási mód.
A lejárt sessionök fájjljai ott hevernek a szerveren és foglalják a helyet. Éppen ezért a PHP általában minden ezredik hívás után (véletlenszerűen) lefuttat egy szemétszedő algoritmust, amely letörli a szerverről a lejárt sessionok már nem használható fájljait.
Néhány fogalom
Serializálás: Az a művelet, amikor egy változó (tömb) adataiból olyan string jön létre, amelyben letároljuk a tömbelemek neveit, típusait és értékeit. A serializált adatok az unserializálás során visszakapják eredeti állapotukat. A sessionokön kívül is lehet használni ezt az eljárást.
Unserializálás: Visszaállítja a serializált adatokat eredeti állapotukba:
serialize( tetszőleges adat) : string - Ez a függvény a megadott, tetszőleges típusú adatokból serializált stringet hoz létre. Erőforrás típust nem lehet serializálni!
unserialize( serializált adatstring) : változó - Az eredeti adatszerkezetet kapjuk vissza. Ha a string nem olyan szerkezetű, amelyet serializálás során hoztak létre, akkor a visszatérési érték False.
Ha egy objektumot serializálunk, akkor a visszállítás előtt be kell tölteni az objektumnak megfelelő osztály kódját, mert csak akkor ismeri fel a PHP, hogy milyen szerkezetet tároltunk le.
A sessionök automatikusan serializálják az adatokat tárolás előtt és visszaalakítják azokat a következő oldalon a betöltés után.
Sessionökkel végezhető feladatok
session_start() - az oldalon elindítja a session kezelését. A PHP kód vagy a HTML kód bármiféle adatküldése előtt kell ennek az utasításnak lefutnia, mert a szerver oldalról a sesson azonosítót a válasz fejlécében küldi ki (header). Ha a böngésző küldött session cookie-t a PHP-nak, akkor azt a session-t fogja használni, ha ilyen nevű érvényes session létezik a szerveren. Ha nincsen megadott nevű érvényes session vagy már lejárt, akkor új session-t fog létrehozni.
session_write_close() - Ha már az oldalon nincsen szükségünk a session további kezelésére, akkor ez a függvény lezárja a session-t az oldalon. Letárolja az adatokat a session fájlba.
session_destroy() - megszünteti (érvényteleníti) az aktuálisan megnyitott sessiont. Utána már ez a session nem használható a következő oldalon sem.
session_id(): string - visszadja az aktuálisan betöltött session nevét. Csak akkor szokás használni, ha javascript / JAVA / HTML / segítségével többféle technológiát használunk a webalkalmazáskor. Ezzel lehet például a JAVA kóddal tudatni, hogy éppen mi a session kódja. Használni érdemes akkor is, ha a böngészőben letiltottak mindenféle cookie-t.
Egy beléptető rendszer
Az alábbi minta a tanításom során alkalmazott egyszerű beléptető rendszer. Két fájlból áll:
login.php - ez lépteti be a felhasználót. sikeres belépés után átirányítja a tényleges oldalra
alkalmazas.php - Ez az igazi webalkalmazás...
A felhasználói neveket és a hozzájuk tartozó jelszavakat nyíltan tárolom (ami nem szép dolog), de ez csak egy példa. A login.php tartalmaz egy login függvényt, amely a felhasználó nevét és jelszavát ellenőrzi. Ha az adatokat például egy mysql adatbázisban tároljuk, akkor csak ezt a függvényt kell átírni.
login.php
<?php
// beléptető függvény
function login($n,$p) {
$tu = array("Pista", "Geza", "Feri", "xxy");
$tp = array("12345","54321","asdfghjk","xxy");
$i= 0;
$db = count( $tu );
while( $i<$db && $n != $tu[$i] && $p != $tp[$i]){
$i++;
}
Return ($i< $db);
}
session_start();
if(isset($_GET['out'])) session_destroy();
if(isset($_SESSION["belepve"]) && $_SESSION["belepve"]){
header("location: alkalmazas.php");
die();
}
if( ( isset($_POST["nev"] ) && isset( $_POST["pwd"] ) ) ) {
$nev = $_POST["nev"];
$pwd = $_POST["pwd"];
$ok = login($nev,$pwd);
if($ok){
$_SESSION["belepve"] = true;
session_write_close();
header("location: login.php");
die();
}
$msg = " Próbálkozz mégegyszer, mert hibás a név vagy a jelszó";
}else{
$nev = "";
$msg = "Kérem a nevet és a jelszót";
}
?>
<html>
<head></head>
<body>
<?php print($msg); ?>
<br>
<form method="POST">
<INPUT TYPE="text" NAME="nev" VALUE="<?php print($nev); ?>"><br>
<INPUT TYPE="password" NAME="pwd"><br>
<INPUT TYPE="submit"><br>
</form>
</body>
</html>
alkalmazas.php
<?php
session_start();
if(!(isset($_SESSION["belepve"]) && $_SESSION["belepve"]) ){
header("location: login.php");
die();
}
?>
<html>
<head>
</head>
<body>
<?php
print " Happy Sunshine, azt csinálunk, amit akarunk!!!!<br/>";
print "<a href='login.php?out=1' target='_self'>Kilépés</a>";
?>
</body>
</html>
A fenti alkalmazásban nagyon egyszerűen lehet létrehozni a kiléptetés funkciót is, de ez már a tanulók dolga...
Itt lehet megnézni a sessionok kezelésének összes lehetőségét: https://www.php.net/manual/en/book.session.php
Beléptetés két faktoros azonosítással vagy Captcha használatával
A két faktoros azonosítás azt jelenti, hogy a felhasználói név és jelszón kívül egy további adatot is meg kell adnunk a webalkalmazásnak. Ezt a további adatot az alkalmazás véletlenszerűen generálja és küldi el a belépő felhasználónak, akinek az elküldött adatot is be kell vinnie a beléptető űrlapon.
A további adatot más felületre, más eszközre küldi a webalkalmazás. Ilyen lehetőség a mobiltelefonra küldött SMS vagy egy megadott email címre küldött email. Természetesen a szoftver előállításához szükség van egyéb infrastruktúrára is, mint például SMS küldési vagy email küldési lehetőségre is. Különösen az SMS-ek küldése pénzbe kerülhet a szolgáltatónak.
Mi az ilyen beléptetés elméleti alapja?
Először is a felhasználó regisztrációja során létre kell hozni kötelezően a telefonszámot vagy az email címet is a felhasználó adatainak rögzítésekor. Ez az adat egyébként az "elfelejtett jelszó" esetén is jól jön.
A belépéskor a felhasználó elküldi a felhasználói nevet és jelszót, amelyet a szerver oldal leellenőriz hasonlóképpen, mint fent láttuk. Ekkor létrejön a felhasználó azonosítói session, de az állapota még nem belépve, hanem belépésre várva. Pl: $_SESSION['logging'] = 'wait'
Ekkor véletlenszerűen generál az alkalmazás mondjuk egy 6 jegyű számot ( 1 millió lehetőség), amelyet a sessionbe is lement, mondjuk $_SESSION['twofactor'] = mt_rand(100000, 999999);
Ezt a kódot kiküldi emailben vagy SMS-ben a felhasználónak. Erre van néhány ingyenes lehetőség. Ilyen például a https://www.textlocal.in/ oldal. A használata a PHP mail függvényének vagy a curl librarynak a használatát igényli. Regisztrálni kell az SMS küldő platformon felhasználóként, majd a megfelelő, itt nem részletezett kódot használva kell küldeni SMS-t a telefonra.
Az oldal meghívja saját magát a korábban beírt usernév, jelszóval, amit már az űrlapon nem módosítható formában jelenít meg viszont beírhatóvá teszi a two factor kódot.
Leellenőrzi a usernév, jelszó, two factor kódot egyszerre és ennek alapján állítja be a $_SESSION['logging'] = 'logging' állapotot.
További megfontolások:
Az első belépési űrlap kitöltése során még nem kell megjeleníteni a two factor lehetőség bevitelét.
A session kezelés biztonságosabb á tétele érdekében használjuk az itt található beállításokat: https://www.php.net/manual/en/session.security.ini.php
Fontos: A sessionoknak legyen lejárati idejük rövid. Ha a böngészőből kilép, akkor járjon le a session. A sessionok beállításait a
ini_set('paraméter', érték);
utasítással tudjuk beállítani.
A hozzá szükséges kódot nem fogom tárgyalni, mert ez túllép a jegyzet keretein.