ugrás a tartalomhoz

Bejelentkezési rendszer megvalósítása

rockybro · 2011. Jún. 22. (Sze), 13.43
Üdv!

Egy loginrendszeren dolgozom, amely az automatikus bejelentkezés funkcióval is fel lenne vértezve. Szeretném az egészet a lehető legoptimálisabban elkészíteni, azaz ne okozzon felesleges terhelést, de legyen kellően biztonságos. Ezzel kapcsolatban merültek fel megvalósításbeli kérdéseim.

1. Munkamenetkezelés: fájlokon vagy adatbázison alapuljon?
Több helyen találkoztam már azzal az ötlettel, hogy a PHP alapértelmezett fájlokon alapuló munkamenetkezelését átültetik adatbázisra.
(Van mondjuk egy sessions tábla, egy sor egy munkamenet adatait tartalmazza, az oszlopok pedig a munkamenet-változók plusz a session id. Így ha van a látogatónak session_id-je, akkor oldalletöltésenként legalább egy sql-lekérdezésre van szükség a munkamenethez tartozó adatok lekérdezése miatt; sőt ha az adatbázisban szeretnénk meghosszabbítani a munkamenet lejárati idejét, akkor 2 lekérdezésre is szükség lehet oldalletöltésenként.)
Ezt a két módszert (adatbázison illetve alapértelmezetten fájlokon alapuló) szeretném összehasonlítani, amire pedig konkrétan kíváncsi lennék:
(a) Melyik produkál gyorsabb sebességet, és ez hogy változik látogatottságtól függően (már ha változik)?
(b) Az adatbázis vagy a fájlkezelés(?) adja meg előbb magát, ha a terhelés növekedik? (nyilván nem néhány látogatóra gondolok)

2. Automatikus bejelentkezés: 1 cookie vagy 2 cookie?
Automatikus bejelentkezés nélkül könnyen elboldogultam: sikeres bejelentkezéskor indítottam egy sessiont, belepakoltam a szükséges adatokat a felhasználóról, plusz némi ellenőrző adatot (user agent + lejárat).
Amikor az automatikus bejelentkezésen törtem a fejem, az első ötletem az volt, hogy mért ne hosszabbítanám meg egyszerűen a session cookie lejáratát (ne a böngésző bezárásakor, hanem mondjuk x nap múlva járjon le), a munkamenet pedig ugyanazokat az adatokat tartalmazná, mint automatikus bejelentkezés nélkül. Ez nem tudom mennyire elegáns, megszokott megoldás, mondjátok meg Ti!
A másik megoldás, ami eszembe jutott: sikeres (automatikus) bejelentkezés esetén generálunk egy hash-t (innentől nevezzük mondjuk login_id-nek). Ezt a login_id-t elhelyezzük cookieban, kap egy jó hosszú lejárati időt. Ezenkívül feltöltjük adatbázisba a login_ids táblába, ahol mellékerül, hogy melyik felhasználóhoz tartozik, illetve az ellenőrző adatok (user agent + lejárat). Indítunk egy sima munkamenetet is (más id-vel), feltöltjük a szokásos adatokkal, plusz beletesszük egy munkamenet-változóba a login_id-t is.
Így ha jön a felhasználó sessionnal, szokásosan leellenőrizzük a munkamenetet, valamint megnézzük, hogy a munkamenetben tárolt login_id megvan-e cookieban a felhasználónak. Ha oké, beengedjük. Ha pedig session nélkül jön a felhasználó, de van login_id cookieja, akkor lekérdezzük adatbázisból a login_id-t és a hozzá tartozó adatokat, ha minden stimmel, indítunk egy munkamenetet, amit újra feltöltünk a szükséges adatokkal.

Mi a véleményetek a két megoldásról? Ti hogy oldjátok/oldanátok meg?

Előre is köszönöm!
 
1

Memória

Poetro · 2011. Jún. 22. (Sze), 14.27
És természetesen lehet memória alapú munkamenet kezelést is megvalósítani APC, Redis, Memcached segítségével. Ugyanakkor ez azt eredményezi, hogy amennyiben a használt szolgáltatás újraindul, akkor elvesznek a session adatok is (Redis alatt elkerülhető perzisztencia használatával). Ekkor nincs igazi adatbázis lekérdezés, bár a fenti szolgáltatásokra tekinthetünk adatbázisként is, de mindenképpen több nagyságrendbeli a sebességkülönbség.
2

Lévén az alkalmazásod

Joó Ádám · 2011. Jún. 22. (Sze), 15.30
Lévén az alkalmazásod alapvetően a relációs adatbázisra épül, kézenfekvőnek tűnik a munkameneteket is ott tárolni. Ha egyébként is csatlakozol az adatbázishoz az oldal előállításakor, akkor szerintem teljesítmény szempontjából is jobb. Ha lemez helyett memóriában tartod, akkor a kérdés fel sem merül.

Ami az azonosítás élettartamát illeti, attól függ, hogyan határozod meg a munkamenet fogalmát és mi a célod. Hogyha az időbelisége számodra lényegtelen, akkor megteheted, hogy hosszú élettartamú munkamenet sütit hagysz a böngészőben.

PHP-ban ez megosztott kiszolgálón körülményes, mert ha a munkamenetek egy könyvtárban vannak tárolva, hiába állítod magasabbra a session.cookie_lifetime értékét, a különböző alkalmazások session.gc_maxlifetime beállításai közül a legalacsonyabb érték fogja eldönteni a munkamenet hosszát.

A magam részéről hajlok arra, hogy a munkamenet érjen véget a böngésző bezárásakor, mert ez a legbiztonságosabb, és egyúttal az elfelejtett jelszavak számát is csökkenti. A felhasználó még mindig használhatja a böngészőt a jelszavak tárolására, ha kívánja.
3

A Redis vagy a Memcached a

bb0072 · 2011. Jún. 24. (P), 13.28
A Redis vagy a Memcached a legjobb session-ök tárolására, de ha nem osztott rendszeren vagy, akkor a php saját default sessionkezelését is használhatod. Az adatbázist nem javaslom, mert szükségképpen cache-eletlen query-ket kell indítanod.

A session cookie általában a böngésző bezárásáig él (ez az alapértelmezés is). Az autologint érdemesebb az általad leírt második megoldással megvalósítani, tehát egy hosszú lejáratú másik cookie-val, amiben valami hash code van (ez lehet például a regisztrációs kód, ami a regisztrációt aktiváló linkben szokott lenni). Ha ez a cookie létezik, de még nincs belépett user, akkor (session-önként egyszer) ellenőrizni kell, hogy érvényes-e a kód, és melyik userhez tartozik. Ekkor még mindig nem kell adatbázisban tárolni a session-öket, csak a userek adatait.

Logout linkre kattintva töröld az autologin cookie-t, különben a következő oldalletöltéskor megint be lesz jelentkezve.