[php] test skryptu logowania

0

Witam, napisałem ostatnio sobie klasę która ma za zadnie logować do systemu admina. Administratorów będzie kilku, w związku z czym nie ma typów użytkowników, i chciałem się dowiedzieć na ile skrypt jest bezpieczny, a co jeszcze trzeba w nim poprawić.

<?php
	class Login {
		
		public $user;
		
		public function re_start(){ // zerowanie sesji po wejsciu na strone index.php - strona logowania
			if (!session_id()){
				session_start();
				$_SESSION['user_id'] = 0; 
			} 
			else {
				session_destroy();
				session_start();
				$_SESSION['user_id'] = 0;
			}	
		}
		
		public function check_sess(){  // sprawdzanie sessji po wejsciu na strone index2.php - strona admina
			session_start();
			if (empty($_SESSION['user_id']) || ($_SESSION['user_id'] < 0)){
				header('Location: index.php');
				exit;
			} else
				return $_SESSION['user_id'];
		}
		
		private function user_correct($login,$password){    // sprawdzanie poprwanosci uzytkownka, jesli user jest dobry zwraca jego id, jeśli zły to zwraca -1
			$result = mysql_query("SELECT id FROM users WHERE `login` = '".mysql_real_escape_string($login)."'");
			$row = mysql_fetch_row($result);
			if (!empty($row[0])){
				$id = $row[0];
				$pass = sha1($password);
				$result = mysql_query("SELECT password FROM users WHERE `id` = '".$id."'"); 
				$row = mysql_fetch_row($result);
				if ($row[0] == $pass){
					return $id;
				} 
				else{
					return -1;
				}
			}
			else	
				return -1;
		}
		
		private function log_in($id){  // logowanie użytkownika, jesli id jest mniejsze lub rowne 0 to przekierowywuje na strone logowania
			session_start();
			$_SESSION['user_id'] = $id;
			if ($id <= 0){
				header('Location: index.php?blad=1');
				exit;
			}
			else {
				header('Location: index2.php'); // jesli id jest wieksze od 0 to user zostaje przekierowany na strone z panelem admina
				exit;
			}
		}
			
		public function action($login,$password){  // wykonanie dwoch funkcji prywatnych po wyslaniu formularza z loginem i haslem
			$id = $this->user_correct($login,$password);
			$this->log_in($id);
		}
		
		public function logout(){   // niszczenie sesji i wylogowanie usera
			session_start();
			$_SESSION['user_id'] = 0;
			$del = session_destroy();
			if ($del){
				header('Location: index.php?opcja=2');
				exit;
			}
		}
	}	
?>
0

Pierwsze co się rzuca w oczy, to brak konstruktora klasy, inna kwestia że powininien to być singleton.

Brak konstruktora powoduje takie kwiatki jak powtórzenia

session_destroy(); session_start();

poza tym session_destroy() usuwa Ci wszystkie dane związane z sesją, nie potrzebujesz robić tego ręcznie.

Metoda re-start() jest kompletnie nie potrzebna.

Dużo by można pisać, poziom bezpieczeństwa jest hmmmyy zerowy.

Polecam zaglądnąć do książki PHP Zaawansowane programowanie, tam jest dobra namiastka takiej klasy właśnie.

0

Konstruktora nie dałem bo to pierwsza klasa jaką pisałem i nie wiedziałem jak on działa. Teraz już wiem to poprawie. Metoda re-start polega na tym że jeśli admin na stronę logowania to zostaje wylogowany i musi się jeszcze raz logować, lub jeśli się nie wyloguje to zostaje przekierowany do index.php i sesja i tak zostanie zniszczona. Jeśli mógłbyś bardziej rozwinąć to że bezpieczeństwo jest zerowe, bo przecież coś ten skrypt robi, tak?

0

@GhostDog:
Wypada jednak zauważyć, że autor przynajmniej trochę się postarał. Zobacz sobie np. to, co wymodził Perykles. W kodzie Peryklesa hasła są zapisywane w bazie jawnie -- tutaj są hashe. W kodzie Peryklesa zmienne wstawione są na pałę do zapytania SQL bez żadnego unieszkodliwiania, co jest niesamowitą wręcz, ziejącą japą w kodzie -- tu jest użyta funkcja, w dodatku ta właściwa (mysql_real_escape_string). Więc corey przynajmniej przyłożył się do tych podstaw, czego nie da się powiedzieć o wielu skryptach wklejanych tu na forum. Dodatkowo sam napisał swój kod i może dopiero się uczy, to jednak jest chyba kimś, komu warto pomagać. Choć przyznam, że sam w takich wypadkach nieraz piszę trochę bardziej "oschle", bo jak gościu potrafi samodzielnie myśleć i uwzględnia takie rzeczy jak bezpieczeństwo, to można go skierować do książek i da radę je zrozumieć i wykorzystać.

@corey:
GhostDogowi zapewne chodziło, że Twoja implementacja jest stosunkowo prosta i nie posiada żadnych dodatkowych, zaawansowanych zabezpieczeń. Przykładowo, nie masz tam żadnych zabezpieczeń przed atakiem słownikowym na hasło. Łącza są dziś coraz szybsze, maszyny też. Ale ludziom wciąż nie chce się pamiętać pokręconych haseł. Dzięki postępowi technologicznemu serwer można zasypać dużo większą liczbą żądań, które sprawdzałyby po kolei różne hasła ze słownika (z pewnymi wariacjami typu dodanie na koniec jednej lub dwóch liczb). Co jednak zrobi serwer z Twoim skryptem, jeśli wyśle mu ktoś 1000 żądań? Ano bardzo chętnie je obsłuży i powie, że nie, te 1000 haseł nie było tym właściwym. I po którymś tysiącu nastąpi zalogowanie. Całość ataku może zająć np. godzinkę, czy nawet dużo krócej.

Zabezpieczeniem byłoby tu wprowadzenie blokady, że po podaniu np. 3 nieprawidłowych haseł trzeba poczekać 10 minut. I dzięki temu małemu ruchowi w ciągu jednej godziny da się sprawdzić zaledwie około 20 haseł, a nie iluś tam tysięcy.

Podobnie, nie ma tu dodatkowych zabezpieczeń np. przed przechwyceniem sesji (co jednak jest już ciut wyższą szkołą jazdy i tak czy siak nie zapewnia 100% skuteczności).

Ogólnie polecam zapoznanie się z tą książką, którą wymienił @GhostDog. O ile pamiętam, tam był wręcz gotowy skrypt do logowania. W dodatku był w miarę szczegółowo omówiony. W ogóle ta kniga to bestseller, być może najlepsza dostępna książka o PHP. Na pewno Ci się przyda. Ja mam ciut starsze wydanie i poważnie się zastanawiałem, czy nie kupić najnowszego (znacznie ładniejszego, swoją drogą).

Zapewnienie takiego prawdziwego, porządnego bezpieczeństwa przy logowaniu jest naprawdę troszkę skomplikowaną sprawą i po prostu warto o tym poczytać, bo ta wiedza zawsze się przyda.


Przy okazji mogę Ci powiedzieć jeszcze parę rzeczy, których nie znajdziesz w książce "PHP. Zaawansowane programowanie" (bo niestety już chyba postanowiliśmy za Ciebie, że ją kupujesz ;-) ). Rzeczy te są ważne i dotyczą jakości i czytelności kodu. Nie będę tego analizował bardzo głęboko, ale zwrócę Twoją uwagę na kilka prostych, ale ważnych rzeczy.

Niejednolite/niepoprawne nazwy funkcji. Porównaj kilka funkcji, które tam masz:

function re_start() { ... }
function log_in() { ... }
function logout() { ... }

re_start pisze się razem: restart. Tak samo masz log_in, ale masz logout. Podejrzewam, że nie chciałeś mieszać nazwy akcji (czasownik log in -- zaloguj) i nazwy użytkownika (login jako nazwa użytkownika). W takim wypadku jednak powinieneś nazwać tę drugą funkcję log_out lub log_off. W razie wątpliwości odpal dictionary.com i sprawdź.

Zduplikowany kod w gałęziach wyrażenia warunkowego. To popularny błąd, choć jak na dłoni widać, że przeczy zasadzie DRY. Masz tak:

public function  re_start(){
  if (!session_id()){
    session_start();
    $_SESSION['user_id'] = 0;
  }
  else {
    session_destroy();
    session_start();
    $_SESSION['user_id'] = 0;
  }
}

To samo możesz zapisać tak, bez zbędnych powtórzeń (przy okazji poprawiłem nazwę):

public function  restart(){
  if (session_id()) {
    session_destroy();
  }
  session_start();
  $_SESSION['user_id'] = 0;
}

Podobną zmianę wypadałoby też wprowadzić do funkcji log_in.

Niezbyt trafne nazwy funkcji. Zobacz na funkcję user_correct($login, $password). Po samej nazwie można by sądzić, że funkcja tak naprawdę powinna się nazywać is_user_correct i zwracałaby TRUE, gdyby login i hasło się zgadzały lub FALSE w przeciwnym wypadku. Tymczasem prawdziwe działanie funkcji musiałeś opisać w komentarzu: funkcja zwraca normalnie id użytkownika na podstawie loginu i hasła, a gdy te do siebie nie pasują, zwraca -1. Trzeba ja więc nazwać od jej głównej funkcji, czyli po prostu get_user_id($login, $password). Tu po samej sygnaturze można się domyślić, że zwraca ona ID, a nie TRUE czy FALSE.

Tak samo nazwanie funkcji "action" może być odrobinę kontrowersyjne. Mogłoby być całkiem OK gdyby klasa była komendą, ale wtedy nie powinna zawierać funkcji log_out. Dostępna publicznie funkcja wykonująca zalogowanie mogłaby się nazywać log_in, a ta od wylogowania log_out. Funkcja prywatna, która loguje użytkownika o danym id, mogłaby się nazywać login_user_with_id($id). Jeśli w tym momencie wkurzałoby Cię, że klasa nazywa się Login i ma metodę log_in, to klasę możesz nazwać np. LoginManager lub po prostu Authentication / Auth.

0

Przyznam się, że raczej pobieżnie popatrzyłem ten kod (bo nie miałem czasu) i nie zauważyłem funkcji:

mysql_real_escape_string

, co się chwali, zwłaszcza, że nawet autorzy książki podanej przeze mnie, zdają się jakby kompletnie zapominać o wstrzykiwaniu sql...

Post mógł się wydać oschły (jak to napisał @bswierczynski), z braku czasu tak napisałem.
Książkę PHP ZP spokojnie znajdziesz w sieci, także masz możliwość sprawdzenia czy Ci podchodzi. Są w niej rozdziały, których kompletnie nie da się czytać. Jest autorstwa 4 osób, i daje się zauważyć, że jedna z nich (prawdopodobnie) chciała za wszelką cenę udowodnić swoją programistyczną zajebistość (dokładnie chodzi mi rozdział o mvc - jak dla mnie jest to totalne nie porozumienie, choć pewnie znajdzie się wielu co mnie zbluzga za tą opinię), ale tak poza tym to 7.5/10 się należy. Swego czasu napisałem nawet opinie o tej książce na helionie, ale jakoś nie zwykli są publikować moich recenzji...

@corey piszesz o braku podstaw OOP w PHP.
W mojej opinii wszystko powinno być w pełnej symbiozie, czyli najpierw teorie OOP masz w małym paluszku, a później zabierasz się za pisanie praktycznych skryptów.

No więc tutaj polecam trochę inną książkę:
PHP Objects,Patterns, and Practice (Apress)

Szukałem kiedyś polskiej wersji, nigdzie jej nie ma, a na helionie nakład został wyczerpany.
Mam pdf ang i śmiem twierdzić, że ta książka nauczy Cię lepiej oop niż PHP ZP.
Jednak szczegóły związane z rozwiązaniem praktycznych problemów są opisane właśnie w PHP ZP, najlepsza byłaby lektura obu.

Pozdrawiam

0

Nawiążę może jeszcze do książek, które mogłyby tu się przydać. Jeśli ktoś chce wyjść poza hashowanie haseł u unieszkodliwianie wejścia, to powinien dużo czytać -- czy to w necie, czy z książek.

Tego ZP nie uważam ogólnie za super wypasioną książkę. Gdy ją kupiłem, to bałem się, że będzie jednym z niewielu faili, jakie nieopatrznie kupiłem. Styl pisania nie był taki super, a i niektóre przykłady wydawały mi się niekompletne/niedokończone. W dodatku kończyły się w miejscach, które mnie interesowały, co byłoby może OK, gdyby wytłumaczenie dalszych działań w tekście było satysfakcjonujące (a IMO nie było). Pisałem nawet na (innym) forum, czy ktoś nie zna czegoś lepszego do PHP i ew. baz danych (MySQL czy czegokolwiek). No i wszyscy polecali właśnie ZP. Sporo nad tym dyskutowałem i wyszło nam, że faktycznie książka nie jest taka zła i komuś, kto sam myśli i nie chce tylko gotowców, ale chce zrozumieć te i inne problemy z PHP -- jest to prawdopodobnie najodpowiedniejsza pozycja. Na pewno poruszają zaawansowane rzeczy, łącznie z pisaniem rozszerzeń do PHP, choć książka jest tak gruba i ma tyle informacji, że nawet jak kogoś rozszerzenia nie interesują, to nie jest tak, że mu się nagle nie opłaci kupić.

Z drugiej strony muszę powiedzieć, że znam dużo książek ZNACZNIE lepiej napisanych. Z tych ogólnych to przykładów jest dość sporo, od słynnego "Pragmatycznego programisty" począwszy. A o językach programowania to do JavaScriptu mamy malutką "JavaScript -- Mocne strony Douglasa Crockforda". Do CSS mamy Meyera, który może nie rzuca dowcipami na prawo i lewo, ale pisze dość przyjemnie i płynnie i wszystko omawia po kolei i bardzo szczegółowo. Do semantycznych layoutów w CSS/HTML mamy też "Kuloodporne strony internetowe" (Dan Cederholm), również moim zdaniem lepiej napisaną niż ZP do PHP.

A do bezpieczeństwa... Pod tym względem całkiem sporą wiedzę wyniosłem z uczelni, gdzie mieliśmy to troszkę wałkowane, a materiały do wykładów były porządne. Ale jest jedna książka, którą mogę polecić: "Bezpieczeństwo aplikacji tworzonych w technologii Ajax". Fakt, wyraźnie koncentruje się na Ajaxie (bo na pewno nie na PHP), tj. pokazuje, czemu aplikacje ajaxowe są bardziej narażone niż aplikacje w czystym PHP (przykładowo). Teraz Ajax jest tak "modny", że chyba bardzo wielu programistów PHP-a musi mieć z nim do czynienia. A jeśli piszą również komponent po stronie klienta, to prawie lektura obowiązkowa. Lepszej książki o bezpieczeństwie jeszcze nie czytałem. Napisana bardzo fajnie (ZP się chowa, ale styl pisania nie jest najmocniejszą stroną ZP) i są tam wprost zanalizowane robaki JavaScript, czy konkretne ataki. Ba, książka prawie zaczyna się historyjką, w której hacker (a właściwie hackerka!) dokonuje pełnego ataku na pewną aplikację. Jest to opisane od początku do końca i bardzo szczegółowo -- włącznie z treścią żądań, jakie są wykonywane. Dla mnie lektura była naprawdę przednia, ale ja jestem zainteresowany JavaScriptem, więc nie wiem, czy komuś, komu w głowie tylko PHP książka podpasuje (konkretnie o PHP jest tam bardzo mało, ale corey zna już przecież mysql_real_escape_string [a o prepared statements?] i wie, że np. register_globals jest be ;) ). Ostatnio w Empiku widziałem jeszcze jedną, cieńszą i tańszą pozycję, Testowanie bezpieczeństwa aplikacji internetowych. Receptury. Nie kupiłem jej jeszcze, bo zawierała sporo małych rozdziałów i bałem się, że nie będą one wystarczająco szczegółowe. Muszę jeszcze raz się przejść i przeczytać jakiś rozdzialik na miejscu.

0

Czytałem Wasze posty z wielką uwagą bo każda rada jest dla mnie bardzo cenna. Tym bardziej że jestem dopiero w 3 klasie Technikum Informatycznego, a tam nie ma mowy jeszcze o PHP czy nawet JavaScript, a wszystko co tu prezentuje, w 100% nauczyłem się sam, dlatego jeśli Wasi wykładowcy mówili w jakiś sposób o zabezpieczeniach sesji czy logowania to te uwagi zmobilizują mnie do dalszego ulepszania skrypty pod względem bezpieczeństwa.
Odnośnie tych książek co polecacie to na pewno skorzystam z tej PHP. Zaawansowane programowanie, bo nawet już ją mam ;)

Na razie jedyne pytanie jakie mi się nasuwa dotyczy tego o czym napisał @bswierczynski, a mianowicie nazewnictwo funkcji, zmiennych itd. Czy nazewnictwo ma jakiś wpływ na bezpieczeństwo? Czy mogę sobie nazywać funkcję wg własnego uznania, tak żeby po kilku latach wrócić do skryptu i wiedzieć o co chodzi w której linii, bo jeśli nazywa się to 'po swojemu' to wydaje mi się że w pamięci pozostaje na dłużej.

Na bieżąco będę poprawiał skrypt i dostosuje się do tego o czym mówiliście, po 3 błędnych próbach będzie trzeba odczekać, oraz hasła ze znakami specjalnymi czy i cyframi.
Jeśli nasunie się komuś jakaś myśl, która mogła by zwiększyć bezpieczeństwo to będę bardzo wdzięczny :) Pozdrawiam

0

@corey:
To jak na 3 technikum radzisz sobie zdecydowanie ponadprzeciętnie dobrze. Ludzie na studiach wklejają tu nieraz taki chłam, że głowa boli -- część z nich zresztą wychodzi na całkiem niezłych programistów (więc Ty możesz być nawet bardzo niezłym, jeśli będziesz się przykładał). Bo to normalne, że jak ktoś jest newbie, to robi jakieś błędy i niedociągnięcia. Sęk w tym, żeby się uczyć i żeby zdążyć to zrobić. Skoro Ty jeszcze w technikum robisz to, co robisz, to na pewno zdążysz, jeśli tylko bardzo nie zwolnisz ;).

Co do nazewnictwa to ma ono niewielki wpływ na bezpieczeństwo. Chodzi tu o coś innego: czytelność kodu, wygodę i ew. bezpieczeństwo jego używania ;). Nie ma czegoś takiego jak nazywanie funkcji "po swojemu". Nie nazywaj funkcji kichnij(), jeśli jej zadaniem jest kaszlenie. Nazwa funkcji musi skrótowo opisywać jej działanie. Nazwy powinny być też jednolite, czyli jeśli piszesz log_in, to również log_out. Chodzi o to, byś mógł usiąść przy Twoim własnym kodzie za tydzień, miesiąc, czy rok i byś nie przeżywał niespodzianek typu "czemu log_out nie działa, skoro działa log_in?!" (ano dlatego, bo nazewnictwo jest niespójne i funkcja nazywa się inaczej).

Nazwy przecież i tak sam wymyślasz. I tak robisz to "po swojemu". Zadbaj jednak, by jednocześnie było to logiczne.

Nazewnictwo ma pewien wpływ na bezpieczeństwo. Przychodzi mi do głowy taki przykład... Niektórzy nazywają sobie dane wg schematu np. login_raw i login_escaped (za "login" podstaw dowolny parametr). login_raw to wartość pochodząca prosto z GET-a, POST-a lub innego wejścia, potencjalnie szkodliwa. login_escaped to już wartość po unieszkodliwieniu (np. za pomocą mysql_real_escape_string). W ten sposób zawsze widzisz, gdzie używasz wersji niebezpiecznej (ale dokładnie takiej, jak podał użytkownik), a gdzie bezpiecznej.

Fajnie że masz książkę ZP. Jak widzisz, wbrew pozorom (tj. pewnej... bamberskości :D) jest uważana za całkiem niezłą.

0

Jak na Technikum to brawo, że doszedłeś do OOP.
Ja o swoich wykładowcach od programowania nie mogę powiedzieć nic dobrego, ponieważ niczego mnie nie nauczyli...

Z tym nazewnictwem w PHP to sami twórcy się często motają nie jest jednolite jak np w Java.

Najpopularniejsze (z tego co widzę są dwa):

nazwa_metody();

nazwaMetody();

Jeśli chodzi o funkcje, obierasz sobie jedną ścieżkę i jej się trzymasz.

Poczytaj:

http://framework.zend.com/manual/en/coding-standard.html

Może mi kiedyś to też się uda;)

0

bswierczynski napisał:
"Wypada jednak zauważyć, że autor przynajmniej trochę się postarał. Zobacz sobie np. to, co wymodził Perykles. W kodzie Peryklesa hasła są zapisywane w bazie jawnie -- tutaj są hashe. W kodzie Peryklesa zmienne wstawione są na pałę do zapytania SQL bez żadnego unieszkodliwiania, co jest niesamowitą wręcz, ziejącą japą w kodzie -- tu jest użyta funkcja, w dodatku ta właściwa (mysql_real_escape_string). Więc corey przynajmniej przyłożył się do tych podstaw, czego nie da się powiedzieć o wielu skryptach wklejanych tu na forum. Dodatkowo sam napisał swój kod i może dopiero się uczy, to jednak jest chyba kimś, komu warto pomagać."

Taa, czy to znaczy, że muszę się wziąć za podstawy? :P

0
Perykles napisał(a)

Taa, czy to znaczy, że muszę się wziąć za podstawy?

Ależ nie, skądże! Jeśli nie przeszkadza Ci, że dowolna osoba może wykonać dowolną operację na Twojej bazie danych (w tym np. usunięcie wszystkich rekordów), to nie musisz. No i aby nie musieć, to powinieneś jeszcze mieć gdzieś swoich użytkowników. Bo im może się nie podobać, że dowolna osoba może sprawdzić ich hasło (prawdopodobnie w innych serwisach też mają podobne lub takie same...).

A tak na serio to tak, powinieneś zadbać chociaż o podstawowe zabezpieczenia w swoich aplikacjach ;). Tu gościu chodzi to technikum, a już takie ma i chce mieć lepsze. I dobrze, bo każda szanująca się witryna musi takie mieć. Niestety zapewnienie bezpieczeństwa jest trudne i trzeba trochę o tym poczytać i samemu pomyśleć. Gdy się tego nie zrobi, to można stracić całą bazę danych, hasła użytkowników mogą wyciec, a na Twojej stronie ktoś może dodać dowolnie chamskie treści, podszywając się nawet pod Ciebie. Raczej niemiła perspektywa.

0

Poprawiłem już część kodu, żeby po 3 nieudanych próbach trzeba było odczekać 10 minut. Przy każdej nie udanej próbie logowania wykonuje się taka linia kodu:

setcookie("proba", $_COOKIE['proba']+1, time() + 10 * 60);

Na stronce z formularzem logowania sprawdza zmienną $_COOKIE['proba'] i jeśli jest ona >=3 wtedy kontrolki z loginem, hasłem i przyciskiem są DISABLED i wyrzuca komunikat że trzeba czekać. Może tak być? Czy trzeba to zrobić w bardziej wyrafinowany sposób? ;p

0
corey napisał(a)

Poprawiłem już część kodu, żeby po 3 nieudanych próbach trzeba było odczekać 10 minut. Przy każdej nie udanej próbie logowania wykonuje się taka linia kodu:

setcookie("proba", $_COOKIE['proba']+1, time() + 10 * 60);

Na stronce z formularzem logowania sprawdza zmienną $_COOKIE['proba'] i jeśli jest ona >=3 wtedy kontrolki z loginem, hasłem i przyciskiem są DISABLED i wyrzuca komunikat że trzeba czekać. Może tak być? Czy trzeba to zrobić w bardziej wyrafinowany sposób? ;p

Moim zdaniem warto zrobić to również na sesji, ponieważ cookie łatwo usunąć, w sumie sesję również, wystarczy zamknąć przeglądarkę. Chociaż ja bym zrobił to na bazie, że po trzech próbach wpisuje dane ip do bazy i blokuje na 10min.

0

@corey:
Trzeba to zrobić koniecznie na bazie danych. Cookie nie stanowią żadnej ochrony przed automatami -- wykonujący atak brute-force (lub raczej: atak słownikowy) robot będzie odrzucał to Twoje cookie blokujące. Trzeba to przechowywać po stronie serwera, np. w bazie danych.

Blokadę w bazie danych możesz zrobić na IP czy inną informację sprzętową, ale możesz też zrobić po prostu na daną nazwę użytkownika (tak chyba to było zrobione w książce ZP).

0

Witam ponownie. Zrobiłem tak jak radziliście i blokuje dane ip poprzez wpisanie do bazy.

Ale szukając w necie o bezpieczeństwie sesji natknąłem się na taką funkcję:

session_regenerate_id();

Zmienia id sesji po każdym odświeżeniu strony czy wejściu na inną więc na pewno zmniejsza się ryzyko wykradnięcia PHPSESSID.

0

no @corey w dobrą stronę zmierzasz.

Nie musisz jej używać co każde żądanie, możesz ustalić np, że co 3 żądanie id zostanie zmienione

1 użytkowników online, w tym zalogowanych: 0, gości: 1