Aleksejs Posted July 24, 2008 Report Share Posted July 24, 2008 (edited) Pirms dažām dienām solīju parādīt kā izskatās lietotāju autentifikācija, kas nebalstās uz sesijas mainīgo izmantošanas un kas izmanto "Hardened stateless cookies". Tad nu te ir tas, kas sanācis. Uzreiz brīdinu, ka pārāk briesmīgi ar komentēšanu neesmu aizrāvies, tādēļ ja ir jautājumi pēc būtības par tiem vai citiem izvēlētajiem risinājumiem, centīšos uz tiem pēc iespējas atbildēt. Vēl jāpiebilst, ka kaut arī sapņoju kādreiz nopietni pieķerties OOP, tomēr arī šoreiz kods ir rakstīts procedurāli, tādēļ OOP aizstāvji nesitiet mani. ;) Vispirms sākam ar datubāzes uzbūvi. Esmu pieņēmis, ka lietotāju dati glabājas datu bāzē users: sqls, kas izveido datubāzi un pievieno lietotāju "labietis", kuram uzstāda paroli "parole". (iekš paste.php.lv neielikās): CREATE DATABASE IF NOT EXISTS `WebApp`;CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL auto_increment, `username` varchar(20) NOT NULL, `password` char(128) NOT NULL, `salt` char(128) NOT NULL, PRIMARY KEY (`id`), KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `users` (`username`,`password`,`salt`) VALUES ( 'labietis', '2fe0be79380e195da158a7919bca7c74a262d71a51d96f89b3ce073bedb03048de33c6417c9b 0372532724402d09880fad4e60436ba53be035e1479a9718d2d0', '008f5d0a8d12f7bfec2596d2b248a37745077df60ac29d930c0c3595c6c706519ca7813c2d74 46e0084e6fdd7d028d9927fab1733b75ee722974ebff58f0b6bf'); Tālāk pārejam pie funkcijām: fails auth_common.php satur funkcijas un mainīgos, kas nepieciešami autentifikācijas pārbaudei; fails auth_logon.php satur funkcijas kas apstrādā nehashotas paroles, un kas dabū no lietotājvārda lietotāja ID; fails auth_user_management.php satur funkcijas, kas ļauj izveidot jaunus lietotājus, nomainīt paroli norādot/nenorādot veco paroli kādam no lietotāja ID, kā arī palīgfunkcijas. Tālāk seko piemēri šo funkciju izmantošanā: login lapa: logon.php; autentifikācijas pārbaudes lapa autentifikators.php, kuru paredzēts ar require_once() izsaukt katras aizsargājamās lapas sākumā - kā piemēram te: index.php; logoff lapa: logoff.php būtībā izdzēš autentificēšanas cookie; Administratora lapa user_mod.php lietotāju paroļu (arī savas!!! un tad būs jāielogojas ar jauno paroli, lai turpinātu darbu) nomaiņai. Administratora lapa jauna lietotāja pievienošanai user_add.php demonstrē funkcijas admin_create_user() izmantošanu. Lietotāja lapa savas paroles nomaiņai change_pass.php Cerams, ka kodā kļūdu nav un, nevajadzētu arī darboties SQL injekcijām. Šīs autentifikācijas metodes plusi: Uz servera nav jāglabā sesijas dati (tam ir paredzēts $user_data[5]), līdz ar to var vienkāršāk veidot klāsterus (jo savā starpā nav jāsinhronizē sesijas dati). Cookiju var izmantot tikai no tās pašas IP adreses. Paroles maiņa nākošās darbības veikšanas reizē liek pārlogoties pilnīgi visiem konkrētā lietotāja aktīvajiem pieslēgumiem. Dati cookijā glabājas lietotājam nepieejamā veidā un ir aizsargāti pret manipulāciju. Mīnusi: Nav nojausmas par to cik reizes konkrētais lietotājs ir pieslēdzies. Kas būtu vēl darāms: Jāizveido stored procedures/funkcijas, kurām vienīgajām ir piekļuve laukiem salt/password - visiem pārējiem web-aplikācijā izmantotajiem sql lietotājiem liegt pieeju šiem laukiem un tikai īpašiem autentifikācijas lietotājiem ļaut darbināt stored procedūras. Edited July 24, 2008 by Aleksejs Quote Link to comment Share on other sites More sharing options...
andrisp Posted July 24, 2008 Report Share Posted July 24, 2008 Aleksejs, teikšu tikai vienu. :) Ārprāts cik daudz nestētu kontrolstruktūru!!! http://paste.php.lv/7704?lang=php Quote Link to comment Share on other sites More sharing options...
Aleksejs Posted July 24, 2008 Author Report Share Posted July 24, 2008 Andri - jā ;) Pascal ietekme uz organismu. Quote Link to comment Share on other sites More sharing options...
Toms Posted July 24, 2008 Report Share Posted July 24, 2008 Vai šis būtu vienīgais lielais iemesls, lai nelietotu sesijas? ...Uz servera nav jāglabā sesijas dati (tam ir paredzēts $user_data[5]), līdz ar to var vienkāršāk veidot klāsterus (jo savā starpā nav jāsinhronizē sesijas dati)... Quote Link to comment Share on other sites More sharing options...
Aleksejs Posted July 25, 2008 Author Report Share Posted July 25, 2008 Nē, nav vienīgais. Vēl daži argumenti no manis daudzinātā "Hardened stateless session cookies"[1][2]: ...Also, unless users explicitly log out, the server state associated with a session must be retained until the session times out. This means that the space required on the server for maintaining state can grow much faster than the number of users. This also introduces a denial of service vulnerability, in that attackers could create many sessions and fill up the filesystem. ... ...Even though it is likely that many users will select poor passwords, the inclusion of a large salt prevents operation (3) being enough to brute-force the password. This property is desirable because rate-limiting, to resist online brute-force attacks, need only be applied to the login procedure (2), not every page that requires authentica- tion. This could be particularly valuable in load-balanced situations with one login server and multiple application servers – only the login server need retain state on the number of failed login attempts. ... ...If the attacker is able to read the database, e.g. through unsecured backups or SQL injection, it can discover a user’s authenticator, salt and global MAC key. This is still insufficient to generate a valid cookie, as doing so would be equivalent to discovering the pre-image of a hash output. Būtībā, nav problēma arī šo sistēmu papildināt ar sesijām raksturīgajām lietām - šīs pašas funkcijas sakombinējot ar: http://lv.php.net/manual/en/function.sessi...ave-handler.php iegūstam apvienojumu no abiem - iespēju darboties ar $_SESSION mainīgajiem un šīs shēmas plusus. Pie kam, ja pareizi izveidojam, tad iegūstam, ka jaunu sesiju (PHP izpratnē) izveidot var tikai autentificēts lietotājs, kas neļauj notikt ar pirmo pieminēto citātu saistītajām resursu pārpildīšanās problēmām. Quote Link to comment Share on other sites More sharing options...
codez Posted July 25, 2008 Report Share Posted July 25, 2008 Bet kā tad ar to, ka katrā pieprasījumā, ja sesijas dati ir pietiekami lieli, tie tiek katru reizi sūtīti? Quote Link to comment Share on other sites More sharing options...
Aleksejs Posted July 25, 2008 Author Report Share Posted July 25, 2008 Jā, tā tas notiek. Ja ir lieli (cik lieli ir lieli ;) ) sesijas dati, tad jādomā, ko darīt, vai sūtīt katrā pieprasījumā, vai turēt uz servera, vai arī kombinēt abas metodes. Quote Link to comment Share on other sites More sharing options...
bubu Posted July 25, 2008 Report Share Posted July 25, 2008 Sesijas (ja tiek runāts par iebūvēto php sesiju darbību) datus nekur nesūta. Tie vienmēr glabājas uz servera. Sūtās tikai sesijas id. Quote Link to comment Share on other sites More sharing options...
Aleksejs Posted July 25, 2008 Author Report Share Posted July 25, 2008 Bubu, jā, ar "turēt uz servera" biju domājis tieši iebūvētās PHP sesijas gadījumu. Quote Link to comment Share on other sites More sharing options...
bubu Posted July 25, 2008 Report Share Posted July 25, 2008 To es vispār atbildēju codez'am, ne tev. Quote Link to comment Share on other sites More sharing options...
Aleksejs Posted July 25, 2008 Author Report Share Posted July 25, 2008 Āāāāā :D Quote Link to comment Share on other sites More sharing options...
codez Posted July 25, 2008 Report Share Posted July 25, 2008 bubu, šijā topikā tak runa ir par "Hardened stateless cookies" Quote Link to comment Share on other sites More sharing options...
Roze Posted July 25, 2008 Report Share Posted July 25, 2008 IMHO pārāk bloatēts kods. Vismaz tie nestotie if-i kaut kā neizskatās smuki (proti uzskatu ka statusu var/vajag returnot tikai vienreiz). Bez tam nav pārdomāts arī pašas statusu vērtības - proti: return 7; //viss OK <- nozīmē ka es nekad nevarēšu izpildīt if(user_change_pw(..)) .. jo ir arī šāds 'return 4; //nav izdevies piesaistīt mainīgos' kas nozīmē == 7 .. kas nozīmē ka ja uzrodas jauns statuss tad vai nu viss jābīda uz leju vai arī sanāks ka 7 ir OK bet 8 vairs nav OK :) Smukumam prasītos ja jau izmantojam "state of the art" mysqly nu tad izmantojam funkcijas/procedūras nevis kadreiz prepārojam vienu un to pašu kveriju :) Bez tam (varbūt esmu neuzmanīgs) nemaniju nekādu datu kompresiju - problēma ir tāda ka klientam cookijs jāsūta uz katru requestu. It īpaši ja vēl, piemēram, statiskajam kontentam nav savs domēns tad visi cookija dati gāžas arī uz citiem elementiem kas atrodas piemēram zem domain.lv/img/ .... kas galā var rezultēties un diezgan lielu augšupejošu trafiku. Trešā lieta - pie mums varbūt mazāk, bet lielākoties visur pasaulē vispār atsakās no statiskas IP izmantošanas autorizācijai. To protams pielogo utt, bet tas nav kritērijs pārbaudei (var patestēt google / facebook utt). Tas saistīts ar to ka kaut kādam procentam no lietotājiem ir mainīgas IP (slavens un tā iesācējs ir AOL) .. (korporatīvie proxy, roamings utt utt). .. tās tādas pārdomas. Quote Link to comment Share on other sites More sharing options...
Aleksejs Posted July 25, 2008 Author Report Share Posted July 25, 2008 Nu jā, par koda estētiskumu galīgi nestrīdos - šis jau tikai tāds koncepts, lai paskatītos, kā/vai vispār darbojas. Par statusu returnošanu arī taisnība, pašlaik ir ideja pārtaisīt, ka funkcijas atgriež true/false un attiecīgās vērtības, lai piešķir padotajiem parametriem + vēl kā parametru padot $error_log masīvu, kuram tad kabināt visuas excepcijas, lai beigās varētu korekti sažurnalēt/atgriezt kļūdas paziņojumu. Pie mysql storēto funkciju/procedūru izmantošanas tieši šobrīd darbojos. :) Par kompresiju arī - vakar sāku pētīt, ko var darīt lietas labā, principā jau nekas īpaši vairāk nav - 1 rindiņa gzcompress($data) un viss... Vienkārši atkal sakarā ar to, ka tas bija tikai koncepts, neko īpaši vairāk neveidoju. Kādu kompresijas metodi ieteiktu? Par IP adreses izmantošanu/neizmantošanu arī esmu daudz domājis... Faktiski ar atgriesto statusu jau redz, vai ir mainījusies tikai adrese 6 vai arī nekas nav mainījies 7... Līdz ar to, pēc vajadzības var IP adreses pārbaudi neņemt vērā. Quote Link to comment Share on other sites More sharing options...
4e4en Posted July 26, 2008 Report Share Posted July 26, 2008 ...Uz servera nav jāglabā sesijas dati (tam ir paredzēts $user_data[5]), līdz ar to var vienkāršāk veidot klāsterus (jo savā starpā nav jāsinhronizē sesijas dati)... Manuprāt labāk ir izmantot DB priekš sesiju glabāšanas. Tas arī daudz efektīvākā veidā vienkāršo klāsterēšanu. Un smuks kods, lai to izdarītu: http://lv2.php.net/manual/en/function.sess...ndler.php#81761 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.