[ oliver78 @ 15.08.2005. 21:42 ] @
Ovako, pravim jedan mali CMS sistem i potrebna mi je autentifikacija i validacija korisnika za pristup odredjenoj stranici.
Sve sam uradio, ali me interesuje da li pristup dobar.
Evo kako to vrisim.

1. Da li korisnik ima kljuc sesije?

2. Ima - Slobodan pristup stranici.

3. Nema - Vrsi se logovanje.

4. Ako su podaci koje je dao tacni korisniku se predaje kljuc (upisuje se u bazu).

5. Ako su nisu ispravni vraca se na logovanje sa informacijom o gresci.


Deo 1. mi stvara najvise nedoumica. Ja sam ovo sredio tako sto za tekuci kljuc sesije uzmem USERNAME iz baze i proverim da li taj korisnik ima pravo pristupa tekucoj stranici. Da li je taj nacin ispravan?

Inace u sesiji upisujem username i lastvisit iz baze. Da li je jos nesto korisno?

Hvala
[ _owl_ @ 16.08.2005. 02:35 ] @
Pristup koji se uglavnom koristi na net-u je sledeci.
Kada se uloguje korisnik ima na raspolaganju kljuc sesije (koji se generise na slucajan nacin).
Ako sam dobro shvatio tvoj pristup svako ko zna koji su korisnici ulogovani na sistem moze da im otme sesiju tako sto ce kao svoj session ID poturiti username ulogovanog korisnika.
[ noviKorisnik @ 16.08.2005. 07:38 ] @
??? a kako bi se bukvalno ta otimačina sprovodila?
[ oliver78 @ 16.08.2005. 08:01 ] @
Citat:
_owl_:
Ako sam dobro shvatio tvoj pristup svako ko zna koji su korisnici ulogovani na sistem moze da im otme sesiju tako sto ce kao svoj session ID poturiti username ulogovanog korisnika.


Ne, nego obratno. Za dati kljuc sesije trazi se u bazi username korisnika koji ima taj kljuc.
Znaci, kada se neki korisnik uloguje u bazu mu se upisuje kljuc sesije. Kada se korisnik sa tim istim kljucem ponovo vrati na tu stranicu kljuc sesije je isti. Za taj kljuc trazi se username i proverava se pravo pristupa.

PITANJE: Da li je mozda lakse, a isto tako SIGURNO, u sesiji upisati neku vrednost npr login=1 koja ce voditi racuna o tome da li je korisnik sa tim kljucem ulogovan.
[ broker @ 16.08.2005. 10:49 ] @
Napravi posebnu tabelu koja ce drzati parove session_id / user_id (gde je kljuc tabele session_id).

Kad god neko otvori stranucu, proveri da li za taj session id ima slog, i ako nema dodaj ga, bez obzira da li je korsinik ulogovan ili ne. U tom slogu mozes da pmatis recimo i IP sa koga je sajt otvoren tako da kasnije to mozes da proveravas i ako dodje do promene IP-a (neko pokusava da preotme session id, raskines tu sesiju).

Ako se korisnik i uloguje, onda u slog sesije upises i koji je to user i to ti je istovremeno informacija da je user ulogovan. Nikada nemoj u promenljivama sesije da pamtis statuse kao sto je to da li je user logovan, nego to proveravaj u tabeli.

U ovoj tabeli mozes da pamtis i vreme kada je sesija kreirana, vreme poslednjeg pristupa sajtu, a da brises sve sesije kodkojih korsinik nije pristupao sajtu u prethodnih n minuta i tako cak obezbedis pregled svih aktivnih sesija, tj, trenutan broj poseilaca sajta bez obzira da li su ulogovani ili ne.
[ noviKorisnik @ 16.08.2005. 12:06 ] @
Citat:
broker:
Kad god neko otvori stranucu, proveri da li za taj session id ima slog, i ako nema dodaj ga, bez obzira da li je korsinik ulogovan ili ne. U tom slogu mozes da pmatis recimo i IP sa koga je sajt otvoren tako da kasnije to mozes da proveravas i ako dodje do promene IP-a (neko pokusava da preotme session id, raskines tu sesiju).

Od prevelike brige zna da zaboli glava. Ako sam na dial-up konekciji i pukne mi veza, konektujem se ponovo i naravno dobijam drugu IP adresu, a mene sajt šutne zato što pokušavam da otmem sebi sesiju. Pročitao sam da AOL mreža tako konfigurisana da korisnik na svaki request dobija novu IP adresu (e to je prava dinamika)...
[ obucina @ 16.08.2005. 13:09 ] @
Citat:
broker:Nikada nemoj u promenljivama sesije da pamtis statuse kao sto je to da li je user logovan, nego to proveravaj u tabeli.

Da li možeš da mi objasniš zašto?
[ broker @ 16.08.2005. 15:20 ] @
Citat:
noviKorisnik: Ako sam na dial-up konekciji i pukne mi veza, konektujem se ponovo i naravno dobijam drugu IP adresu, a mene sajt šutne zato što pokušavam da otmem sebi sesiju.


Tako i treba. Sajt treba da ubije staru sesiju a tebi dozvoli da udjes tako sto ces ponovo da se ulogujes. Ako tako ne bi radio onda bi svako na zgodnom mestu i sa malim snifferom mogao da upada na tudje naloge.

Tako radi i ES izmedu ostalog a i svaki drugi forum.


Citat:
obucina:
broker:Nikada nemoj u promenljivama sesije da pamtis statuse kao sto je to da li je user logovan, nego to proveravaj u tabeli.

Da li možeš da mi objasniš zašto?


Zbog sigurnosnih razloga. U promenljvie sesije ne treba stavljati podatke koji mogu da budu od koristi eventualnom provalniku. Umesto da cuvas username, password, status i slicne infroamcije u sesiji, cuvaj ih u tabeli, a na njih se referenciraj nekim podatkom koji cuvas u promenljivoj sesije. Tako nije izlozen nijedan konkretan podatak nego samo kljuc po kome serverska aplikacija dolazi do onog sto mu je potrebno. napadacu spolja, sam kljuc je bezvredna inforamcija, jer nema privilegije da pristupi podacima u bazi - to moze samo serverska aplikacija.


[ noviKorisnik @ 16.08.2005. 15:44 ] @
Samo serverska aplikacija može da pristupi session varijablama, ili grešim negde u osnovnim poimanjima?
[ _owl_ @ 16.08.2005. 20:45 ] @
Nastala je zabuna zato sto podaci o sesiji mogu da se cuvaju i kod klijenta (tj u cookiju) a ne samo na serveru (fajl sistem, baza).
Kada se radi autentifikacija bitno je znati sta se nalazi kod klijenta (posto zlonamerni korisnici mogu da promene te podatke) a sta na serveru (tim podacima pristup ima samo aplikacija).
Dakle kada se korisnik loguje on aplikaciji salje svoj username i password a aplikacija mu vraca neki session_id pomocu koga ce pratiti njegovo kretanje na sajtu i prikazivati mu sadrzaj u zavisnosti od privilegija koje su vezane za taj session_id preko veze username <--> session_id. Sam session_id moze da se cuva u cookiju ili se prosledjuje kroz svaki url na sajtu.

Citat:
oliver78
Ja sam ovo sredio tako sto za tekuci kljuc sesije uzmem USERNAME iz baze i proverim da li taj korisnik ima pravo pristupa tekucoj stranici.

Iz ovoga proizilazi da ti je session_id koji se vraca klijentu nakon logovanja sam njegov username (tj da su ti u svim redovima session tabele polja session_id i username ista)

Citat:
noviKorisnik: ??? a kako bi se bukvalno ta otimačina sprovodila?

U slucaju da njemu autentifikacija radi na prethodno opisan nacin (session_id=username), kada znas da je ulogovan neki korisnik ti kao session_id stavis njegov username i ulogovan si kao i on.
[ noviKorisnik @ 16.08.2005. 21:57 ] @
Oh, pa ne znam kada bi mi palo na pamet da napravim vezu session_id=username. Nisam siguran da je to Oliver mislio u startu, ali sada kad ponovo čitam deluje mi i to moguće.
[ oliver78 @ 17.08.2005. 08:02 ] @
Ne, nisam pravio takvu vezu (session_id=username). Ja sam se oslonio na to da je jako tesko (citaj nemoguce) da server dodeli dva ista kljuca sesije. Tako da ne moze da se desi sledeca situacija:
1. korisnik se uspesno uloguje i upise se kljuc sesije u bazu,
2. korisnik se ne izloguje - ne obrise se kljuc sesije iz baze (prilikom logout-a podesio sam da se u bazu za kljuc sesije postavi 0),
3. sledecem korisniku se dodeli kljuc sesije identican predhodnom,
4. proveri se u bazi i ustanovi da "pera" ima kljuc sesije,
5. slobodan prolaz do mile volje jer je "pera" ADMINISTRATOR bre.

Eh, to je problem.

Ova ideja sa posebnom tabelom za sesije mi se cini interesantnom pa ako moze malo vise da to prokomentarisemo.

Hvala,
javljam se kad se vratim se ipita.
P.S. Nisam pominjao kukije. Posto je rec o blogu za sada mi oni nisu potrebni.



[Ovu poruku je menjao oliver78 dana 17.08.2005. u 09:10 GMT+1]
[ noviKorisnik @ 17.08.2005. 10:06 ] @
Tačka 3 bi trebalo da bude tačka pucanja. E sad, jeste da je praktično nemoguće da server dodeli iste ključeve sesije, ipak možeš i dodatno da se obezbediš generisanjem id-a sesije (npr. nema padanja na tački 3 ako je id timestamp + neki random ostatak).
[ _owl_ @ 17.08.2005. 20:54 ] @
Cekaj jesu li u bezi odvojene tabele koje cuvaju podatke o korisniku i o sesijama. Mozes pomocu nekog ogranicenja na vrednost kljuceva sesije u bazi da onemogucis kreiranje dva ista session_id-a.
[ noviKorisnik @ 17.08.2005. 22:19 ] @
Moram da priznam da mi uopšte nije jasna motivacija za beleženje session_id u bazu, pogotovo ako se radi o ulogovanom korisniku. Jedino možda za statistike, može da se prati svako logovanje pojedinačnog korisnika, kretanje po stranicama sajta, itd (sve ovo u tom slučaju važi i za neulogovanog korisnika, osim što se ne vezuje za korisnički zapis).
[ oliver78 @ 18.08.2005. 01:31 ] @
Citat:
noviKorisnik: Moram da priznam da mi uopšte nije jasna motivacija za beleženje session_id u bazu, pogotovo ako se radi o ulogovanom korisniku. Jedino možda za statistike, može da se prati svako logovanje pojedinačnog korisnika, kretanje po stranicama sajta, itd (sve ovo u tom slučaju važi i za neulogovanog korisnika, osim što se ne vezuje za korisnički zapis).


Pa kako drugacije da se zna da li korisnik poseduje tekuci kljuc sesije. Valjda treba nege da se to upise.
A motivacija je sledeca:
1. Ulogujem se.
2. Izmenim neki post.
3. Pogledam kako izgleda na home stranici.
4. Nisam zadovoljan.
5. Vratim se stranicu za administraciju.
6. Ne moram ponovo da se logujem, jer nisam prekidao sesiju. (Imam kljuc)

(Jeeeee, poceo sam i od obicnog teksta da pravim kod. Strasno. :) )

Citat:
_owl_: Cekaj jesu li u bezi odvojene tabele koje cuvaju podatke o korisniku i o sesijama. Mozes pomocu nekog ogranicenja na vrednost kljuceva sesije u bazi da onemogucis kreiranje dva ista session_id-a.


Da ovo su sada detalji. U principu ono sto sam uradio funkcionise (nadam) se kako treba. Mozda nije lose, kao sto je neko pomenuo, da se napravi posebna tabela za sesije. Pogledacu u nekom gotovom CMS.

Aj, kad dodam "allowed_tags" u delu za administraciju ostavicu username i password za login pa da probate, pa ako neko nesto primeti da javi. Imam privremeni CMS podignut na free serveru. OK?
[ noviKorisnik @ 18.08.2005. 01:54 ] @
Citat:
(Jeeeee, poceo sam i od obicnog teksta da pravim kod. Strasno. :) )

:-)

session_id ti se već čuva u kukiju, ostali podaci sesije su na serveru u fajlu koji odgovara tom id-u. Tako da nema problema da odradiš ovaj scenario, dogod postoji i kuki i fajl. Kuki ti stoji dok je otvoren browser, fajl dvadesetak minuta od poslednje aktivnosti.
[ oliver78 @ 18.08.2005. 16:14 ] @
Citat:
noviKorisnik:
session_id ti se već čuva u kukiju, ostali podaci sesije su na serveru u fajlu koji odgovara tom id-u. Tako da nema problema da odradiš ovaj scenario, dogod postoji i kuki i fajl. Kuki ti stoji dok je otvoren browser, fajl dvadesetak minuta od poslednje aktivnosti.


Nisam primetio kukije. Nisam ih ni koristio.
[ noviKorisnik @ 18.08.2005. 16:31 ] @
Jesi koristio (implicitno) ako su ti default setovanja konfiguracije za sesiju (session.use_cookies = 1).

Testiraj: print_r ($_COOKIE);
[ japan @ 18.08.2005. 17:59 ] @
ok, prica sa session_id radi sve dok se ne iskljuci browser...

kako bi to moglo da se uradi a da korisnik bude autentifikovan i ako je u medjuvremenu iskljucio browser, ili ako je bio neaktivan vise od 20 min?

pretpostavljam da bi moglo sa kukijem veceg trajanja, cija bi se vrednost upisala u bazu, pa se onda poredila vrednost iz baze sa onom iz kolaca svaki put kad se pristupi nekoj strani koja zahteva autentifikaciju? nesto slicno celoj ovoj prici gore?
[ noviKorisnik @ 18.08.2005. 20:12 ] @
Za priču o sesijama www.php.net/session

Default za session.cookie_lifetime je 0, što se odnosi na priču dok je otvoren browser, dok druge vrednosti broje sekunde od poslednje posete. Tako se može ostaviti da kuki stoji godinu dana, manje ili više, po potrebi...

Ali je potrebno i da postoji fajl na serveru da bi cela priča mogla da traje toliko dugo... a tu bi mogla da pomogne baza. Evo scenario:

- neka se sesija zove Sess. Proverimo postoji li $_COOKIE ['Sess']
i) postoji - Startuje se sesija s imenom Sess i idom $_COOKIE ['Sess']. Ako postoji fajl ove sesije, u njemu mora da bude setovana promenjiva SessActive na 1, a ako ne postoji tada nije setovana $_SESSION ['SessActive'] pa se traži serijalizovani zapis sesije s ključem $_COOKIE ['Sess'] u bazi, vadi se slog i deserijalizacijom se restaurira stara sesija. (ako se u bazi ne pronađe ovaj zapis imamo problem, ali ništa nije savršeno)
ii) ne postoji - Startuje se sesija s imenom Sess, setuje $_SESSION ['SessActive'] na 1 i druge inicijalne vrednosti koje želimo da se prate kroz sesiju, sesija se serijalizuje i upisuje u bazu pod ključem ida sesije.

- pri svakoj promeni neke session varijable vrši se serijalizacija sesije i upis u bazu s ključem sesije.

Naravno, zbog sigurnosti postoji u sistemu i opcija za logout koja ubija sesiju.

Druga stvar je što sistem logovanja može da obezbedi povezivanje sesija istog korisnika s različitih računara, itd.

[Ovu poruku je menjao flylord dana 19.08.2005. u 00:22 GMT+1]