Autor: Tomasz Jędrzejewski
Data publikacji: 11.12.2004, 18:09 | Ostatnia modyfikacja: 06.11.2006, 18:29
ArtykuÅ‚ ten pokazuje, jak od zera zbudować wÅ‚asny system sesji, nie majÄ…cy nic wspólnego z sesjami tradycyjnie dostÄ™pnymi w PHP.
Nowa, poprawiona i bardziej aktualna wersja tego artykułu znajduje się tutaj (format PDF, 190 kb).
Co jakiÅ› czas na forum pojawiaÅ‚y siÄ™ problemy z sesjami PHP. I zawsze w takim przypadku doradzaÅ‚em stworzenie wÅ‚asnego mechanizmu, gdyż wedÅ‚ug mnie, ten dostÄ™pny domyÅ›lnie najlepszy nie jest, czego dowodem jest sama ilość pytaÅ„. Jednak z wÅ‚asnego doÅ›wiadczenia wiem, iż zadanie stworzenia wÅ‚asnego odpowiednika nie należy do Å‚atwych nawet dla osób znajÄ…cych siÄ™ na rzeczy, a co dopiero dla poczÄ…tkujÄ…cych! Dlatego postanowiÅ‚em wyjść im naprzeciw i tak oto narodziÅ‚ siÄ™ ten tekst.
Sesja w naszym rozumieniu to mechanizm przekazywania danych pomiÄ™dzy wywoÅ‚aniami strony wychodzÄ…cymi od jednego komputera w obrÄ™bie tego samego serwisu. Za jej pomocÄ… tworzone sÄ… rozmaite rzeczy: od koszyków internetowych (dziÄ™ki sesji towary nie "gubiÄ… siÄ™", gdy internauta zmieni podstronÄ™), po systemy autoryzacji i logowania (phpBB, InvisionBoard i wiele innych). My zajmiemy siÄ™ wykorzystaniem sesji do tego ostatniego zadania. Jednak, jak wspomniaÅ‚em wyżej, nie bÄ™dziemy korzystać z tego, co nam podsunÄ™li twórcy PHP. My pójdziemy dalej i stworzymy wszystko od zera. Da to nam peÅ‚nÄ… kontrolÄ™ nad caÅ‚ym mechanizmem, a także możliwość jego rozbudowy o kolejne elementy, wraz z ich obsÅ‚ugÄ… w samym systemie sesji.
SzczegóÅ‚owe dane sesji bÄ™dÄ… trzymane w bazie, miÄ™dzy stronami przekazywany bÄ™dzie 32-znakowy identyfikator sesji. Jego znajomość umożliwi nam zaÅ‚adowanie caÅ‚ej reszty. OczywiÅ›cie pod pewnymi warunkami. Aby upewnić siÄ™, że dane sÄ… pobierane od wÅ‚aÅ›ciwej osoby, musimy przeprowadzić rozmaite testy. U nas bÄ™dzie to tylko jeden - test adresów IP. Jeżeli adres IP zapisany w sesji bÄ™dzie identyczny z tym, który podaje nam serwer, sesjÄ™ można uznać za prawdziwÄ….
Stare sesje musimy usuwać, dlatego bÄ™dÄ… one zawierać pole z czasem ostatniej aktywnoÅ›ci. PrzestarzaÅ‚e po prostu zostanÄ… prÄ™dzej, czy później skasowane, a w razie potrzeby na ich miejscu stworzy siÄ™ nowe.
Jako że nasz mechanizm posÅ‚uży do autoryzacji, musimy wziąć pod uwagÄ™ także roboty wyszukiwarek internetowych. Wiadomo, że nie mogÄ… one przeglÄ…dać strony na równych zasadach z ludźmi, bÄ™dÄ… wiÄ™c dla nich tworzone pseudo-sesje, nie rejestrowane w bazie danych. Taka pseudo-sesja wyklucza caÅ‚kowicie możliwość logowania siÄ™, stÄ…d też roboty nie dotrÄ… do zasobów, które z jakiÅ› przyczyn chcemy chronić.
System przewiduje tylko dwa predefiniowane typy internautów: goÅ›ci oraz użytkowników (zalogowani). Część zasobów bÄ™dzie dostÄ™pna dla wszystkich, część tylko dla zalogowanych użytkowników. W rzeczywistoÅ›ci stosuje siÄ™ o wiele bardziej rozbudowane systemy autoryzacji i przyznawania uprawnieÅ„, jednak jest to temat na innÄ… bajkÄ™. Próba jego opisania tutaj skoÅ„czyÅ‚aby siÄ™ rozrostem tekstu do niemiÅ‚osiernych rozmiarów.
System podany poniżej wykorzystuje bazę danych MySQL, stąd też potrzebnych nam będzie parę tabelek. Oto ich kod:
CREATE TABLE `sessions` ( `session_id` varchar(32) NOT NULL DEFAULT '', `session_user` int(8) NOT NULL DEFAULT '0', `session_ip` varchar(15) NOT NULL DEFAULT '', `session_browser` varchar(128) NOT NULL DEFAULT '', `session_time` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`session_id`) ) TYPE=HEAP; CREATE TABLE `users` ( `user_id` int(10) NOT NULL AUTO_INCREMENT, `user_name` varchar(32) NOT NULL DEFAULT '', `user_password` varchar(32) NOT NULL DEFAULT '', PRIMARY KEY (`user_id`) ); INSERT INTO `users` VALUES (1, 'luser', MD5('ppp'));
W tabeli sessions znajdują się dwa pola przenoszące jakieś dane o użytkowniku strony. Nie są one konieczne mechanizmowi sesji do działania, stąd też możemy je wykorzystać wedle upodobań. session_user przechowuje ID zalogowanego użytkownika. Jeśli sesja należy do gościa, znajdzie się tu wartość "0". Natomiast session_browser może posłużyć do identyfikacji przeglądarki przy wyświetlaniu listy gości w serwisie. Czas (pole session_time) tradycyjnie już zapiszemy w sekundach od 1.1.1970.
Tabela users wygląda tradycyjnie - ot ID, nazwa użytkownika oraz jego hasło tradycyjnie hashowane MD5.
KlasÄ™ tÄ™ zapiszemy w pliku sessions.php. W niej zawarte bÄ™dÄ… metody sÅ‚użące do Å‚adowania, aktualizacji, tworzenia oraz niszczenia sesji. Jej nagÅ‚ówek wyglÄ…da tak:
<?php define('SESSION_TIME', 3600); define('WEBBOT_S', 0); define('GUEST_S', 1); define('USER_S', 2); define('ANONYMOUS', 0); class session{ var $session_id; var $session_user; var $session_ip; var $session_browser; var $session_time; var $sql_id; var $ip; var $browser; var $type; var $userdata;
Pierwsze pięć pól sÅ‚uży do gromadzenia danych z sesji. Jeżeli dodamy/usuniemy z bazy jakieÅ› pole, powinniÅ›my także wprowadzić zmianÄ™ wÅ‚aÅ›nie tu. Oprócz tego mamy dodatkowe pięć pól peÅ‚niÄ…ce rozmaite funkcje. W $sql_id zapisany jest ID sesji przepuszczony przez funkcjÄ™ mysql_real_escape_string(), która daje nam pewność, że wszystkie znaki specjalne MySQL'a stanÄ… siÄ™ bezpieczne i nie bÄ™dÄ… rozwalać nam zapytaÅ„ (należy tu uwzglÄ™dnić ustawienia magic_quotes!). $ip i $browser to dane o adresie IP, oraz przeglÄ…darce, z której nadeszÅ‚o żądanie otwarcia strony. $type sÅ‚uży do okreÅ›lania typu sesji, a odpowiednie wartoÅ›ci reprezentujÄ… trzy staÅ‚e podane tuż przed klasÄ…: WEBBOT_S (sesja bota wyszukiwarki), GUEST_S (sesja osoby niezalogowanej) oraz USER_S (sesja osoby zalogowanej). Ostatnim polem jest $userdata bÄ™dÄ…ce tablicÄ…, gdzie zapisujemy wszystkie przydatne informacje o osobie zalogowanej. W naszym przypadku jest to tylko ID i jego nazwa.
Przyszedł teraz czas na zaprezentowanie pierwszej metody. Pobierze ona informacje o tym, skąd nadeszło żądanie otwarcia strony, a także sprawdzi, czy nie gości na naszej stronie przypadkiem bot jednej ze znanych wyszukiwarek. Oto stosowny kod:
function spy_guest(){ if(getenv('HTTP_X_FORWARDED_FOR') != ''){ $this -> ip = (!empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : ((!empty($_ENV['REMOTE_ADDR'])) ? $_ENV['REMOTE_ADDR'] : $REMOTE_ADDR ); if(preg_match("/^([0-9]+.[0-9]+.[0-9]+.[0-9]+)/", getenv('HTTP_X_FORWARDED_FOR'), $ip_list)){ $private_ip = array('/^0./', '/^127.0.0.1/', '/^192.168..*/', '/^172.16..*/', '/^10..*/', '/^224..*/', '/^240..*/'); $this -> ip = preg_replace($private_ip, $this -> ip, $ip_list[1]); } }else{ $this -> ip = (!empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : ((!empty($_ENV['REMOTE_ADDR'])) ? $_ENV['REMOTE_ADDR'] : $REMOTE_ADDR ); } $this -> browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : $_ENV['HTTP_USER_AGENT']; if(preg_match('/(lycos|googlebot|slurp@inktomi|ask jeeves|whatuseek|ia_archiver)/i', $this -> browser)){ $this -> type = WEBBOT_S; }else{ $this -> type = GUEST_S; } } // end spy_guest();
Jak widać w ostatnich linijkach, "autoryzacja" bota nie jest aż taka skomplikowana. Wystarczy wiedzieć, jak identyfikuje siÄ™ dany robot, a nastÄ™pnie dopisać do wyrażenia, które dokona już reszty.
Kolejna metoda będzie odpowiadać za wykrycie sesji oraz ewentualne wczytanie jej identyfikatora. Kod będzie wyglądał tak:
function is_session(){ if(strlen($_COOKIE['my_session_id']) == 32){ $this -> session_id = $_COOKIE['my_session_id']; setcookie('my_session_id', $this->session_id, time() + SESSION_TIME); $this -> sql_id = mysql_real_escape_string($this->session_id); return 1; } return 0; } // end is_session();
Teraz opowiem, jak taki ID sesji wyglÄ…da. Otóż posÅ‚uży nam za niego połączenie aktualnego czasu oraz adresu IP goÅ›cia przepuszczone najpierw przez funkcjÄ™ uniqid(), a nastÄ™pnie przez md5() - każdy identyfikator bÄ™dzie siÄ™ wiÄ™c skÅ‚adaÅ‚ z 32 znaków i to nam może posÅ‚użyć do sprawdzenia, czy takowy jest już ustawiony.
Jeżeli wykryta zostanie sesja, skrypt załaduje do pamięci jej ID, a także przedłuży ważność ciastka.
Gdy już wykryjemy, czy sesja istnieje, czy nie, warto zaÅ‚adować jej dane do pamiÄ™ci oraz dokonać niezbÄ™dnych kontroli. PosÅ‚uży nam do tego metoda load_session(). Zwróci ona 1, gdy nie wystÄ…piÄ… żadne błędy podczas kontroli i Å‚adowania sesji.
function load_session(){ $r = mysql_query('SELECT s.*, u.* FROM sessions s LEFT JOIN users u ON (s.session_user <> 0 AND s.session_user = u.user_id) WHERE s.session_id = ''.$this -> sql_id.'' AND s.session_time > '.(time() - 3600)); if($row = mysql_fetch_row($r)){ $this -> session_id = $row[0]; $this -> session_user = $row[1]; $this -> session_ip = $row[2]; $this -> session_browser = $row[3]; $this -> session_time = $row[4]; if($this -> session_user != ANONYMOUS){ $this -> type = USER_S; $this -> userdata['ID'] = $row[5]; $this -> userdata['NAME'] = $row[6]; }else{ $this -> type = GUEST_S; } if($this -> session_browser == $this -> browser && $this -> session_ip == $this -> ip){ mysql_query('UPDATE sessions SET session_time = ''.time().'' WHERE session_id = ''.$this->sql_id.'''); return 1; } } $this -> type = GUEST_S; return 0; } // end load_session();
Wypada mi omówić zapytanie użyte do pobrania danych, gdyż zapewne wiele osób nie zna użytej w nim konstrukcji. DziÄ™ki użyciu przeze mnie konstrukcji LEFT JOIN tabela ON warunek mogÄ™ dołączyć do zbioru wyników informacje o zalogowanym czÅ‚owieku, ale tylko wtedy, gdy sesja należy do kogoÅ› takiego! Tak wiÄ™c jeÅ›li w polu session_user znajdzie siÄ™ 0, rekord dotyczÄ…cy użytkownika nie zostanie dołączony do wyniku, gdzie znajdÄ… siÄ™ tylko dane sesji. W przeciwnym wypadku w jednym elemencie wyniku bÄ™dziemy mieli zarówno sesjÄ™, jak i użytkownika. Tym samym skrypt wykona zawsze tylko jedno zapytanie, zamiast dwóch w przypadku koniecznoÅ›ci zaÅ‚adowania dodatkowych informacji.
Jako że starych sesji nie usuwamy przy każdym żądaniu wygenerowania strony (byłoby to zbyt czasochłonne, w końcu jak często się taka sesja trafia?), musimy dołożyć do naszego zapytania odpowiednią blokadę: s.session_time > '.(time() - 3600).
Czasem się zdarzy, że sesję trzeba będzie usunąć. Posłuży nam do tego ta oto metoda:
function delete_session(){ mysql_query('DELETE FROM sessions WHERE session_id=''.$this->sql_id.'''); setcookie('my_session_id', '', 0); } // end delete_session();
Ustawiam czas ciastka na zero, co w praktyce oznacza jego zniszczenie, gdyż 1.1.1970 minął daaaaaaaaaawno temu.
Kolejne trzy metody bÄ™dÄ… tworzyÅ‚y różne rodzaje sesji. Najpierw zaprezentujÄ™ kod dwóch z nich: do sesji botów, oraz sesji goÅ›ci, gdyż nie wymagajÄ… one specjalnego omówienia.
function bot_session(){
$this -> session_id = '';
$this -> session_user = 0;
$this -> session_ip = $this -> ip;
$this -> session_browser = $this -> browser;
$this -> session_time = 0;
$this -> userdata = array('ID' => 0, 'NAME' => '');
} // end bot_session();
function guest_session(){
$this -> session_id = md5(uniqid($this->ip.time()));
$this -> session_user = 0;
$this -> session_ip = $this -> ip;
$this -> session_browser = $this -> browser;
$this -> type = GUEST_S;
setcookie('my_session_id', $this->session_id, time()+SESSION_TIME);
mysql_query('INSERT INTO sessions VALUES(''.$this->session_id.'', '0', ''.$this->ip.'', ''.mysql_real_escape_string($this->browser).'', ''.time().'')');
} // end guest_session();
Dlaczego zdecydowałem się opisać osobno trzecią metodę, user_session()? Ponieważ nie będzie można tak po prostu stworzyć sobie tego rodzaju sesji. Tu znajdą się wszystkie mechanizmy odpowiedzialne za autoryzację podczas logowania, a sesja zostanie utworzona dopiero wtedy, gdy będą one prawdziwe! Z resztą... proszę zobaczyć:
function user_session(){ $this -> garbage_collector(); $r = mysql_query('SELECT user_id FROM users WHERE user_name = ''.mysql_real_escape_string($_POST['login']).'' and user_password = ''.md5($_POST['password']).'''); if($id = mysql_fetch_row($r)){ if(strlen($this->session_id) == 32){ mysql_query('UPDATE sessions SET session_user = '.$id[0].', session_time = ''.time().'' WHERE session_id = ''.$this->session_id.'''); if(mysql_affected_rows() == 1){ setcookie('my_session_id', $this->session_id, time()+SESSION_TIME); } }else{ $this -> session_id = md5(uniqid($this->ip.time())); setcookie('my_session_id', $this->session_id, time()+SESSION_TIME); mysql_query('INSERT INTO sessions VALUES(''.$this->session_id.'', ''.$id[0].'', ''.$this->ip.'', ''.mysql_real_escape_string($this->browser).'', ''.time().'')'); } return 1; } return 0; } // end user_session();
Dopiero tutaj uruchamiamy metodÄ™ garbage_collector() usuwajÄ…cÄ… stare sesje. Prawdziwość danych sprawdzamy jednym zapytaniem - jeÅ›li zwróci ono jakiÅ› rekord, dane sÄ… prawdziwe i można:
Ostatnia metoda ładnie posprząta po nieużywanych sesjach:
function garbage_collector(){ mysql_query('DELETE FROM sessions WHERE session_time < '.(time() - SESSION_TIME)); } // end garbage_collector(); } ?>
Teraz maÅ‚a wskazówka dla osób pragnÄ…cych napisać coÅ› w rodzaju "Ostatniej wizyty zalogowanego użytkownika na stronie". Robi siÄ™ to w ten sposób: do tabeli z użytkownikami dodaje siÄ™ pole w stylu user_lastvisit, natomiast w ww. metodzie przed zapytaniem DELETE dodaje siÄ™ jeszcze jedno, wyglÄ…dajÄ…ce mniej wiÄ™cej tak:
UPDATE users, sessions SET user_lastvisit = sessions.session_time WHERE sessions.session_time < '.(time() - SESSION_TIME)
I po sprawie! W niektórych bazach można to zapytanie przerzucić do triggerów, oszczÄ™dzajÄ…c tym samym kod PHP :).
Chwila, chwila! Przecież nasz kod w takiej postaci jest praktycznie bezużyteczny! Trzeba go jeszcze poskładać w całość. Kod dokonujący autoryzacji znajdzie się w pliku auth.php. Zdefiniowałem tu jedną funkcję - do_auth(), jednak jest ona potrzebna tylko mechanizmowi i nie musisz jej znać. Stworzyłem ją, gdyż zawarta w nim część kodu powtarzała się trzy razy w mechanizmie i po prostu zostawienie tego w wersji pierwotnej zagmatwałoby kod. A tak wiadomo, że jak jest do_auth(), to tu nastąpi autoryzacja danych z formularza do logowania i ewentualne wyświetlenie błędu.
<?php function do_auth(){ global $session; if($_GET['auth'] == 'login'){ if(!$session -> user_session()){ error('Nieprawidłowy login i/lub hasło'); die(); }else{ header('Location: index.php'); die(); } } } // end do_auth();
Pierwszym krokiem robionym przez mechanizm jest stworzenie obiektu klasy session oraz obsÅ‚uga sesji botów wyszukiwarek:
$session = new session; $session -> spy_guest(); if($session -> type == WEBBOT_S){ if(defined('LOGIN_REQUIRED')){ die('Access denied'); } $session -> bot_session();
Gdy mamy do czynienia ze zwyczajnÄ… sesjÄ…, możemy spróbować zaÅ‚adować jej dane. OczywiÅ›cie boty nie majÄ… dostÄ™pu do stron, do których wymaga siÄ™ logowania, co widać powyżej.
}elseif($session -> is_session()){ if($session -> load_session()){ do_auth(); if(defined('LOGIN_REQUIRED')){ if($session -> type != USER_S){ form_request(); die(); } } if($_GET['auth'] == 'logout'){ $session -> delete_session(); $session -> guest_session(); header('Location: index.php'); }
Strona powiadamia mechanizm, że potrzeba na niÄ… logowania poprzez stałą LOGIN_REQUIRED. Gdy jest ona ustawiona, dokonuje siÄ™ sprawdzenie, czy mamy do czynienia z sesjÄ… usera, a jeÅ›li nie - wyÅ›wietlamy delikwentowi formularz. Tu także obsÅ‚ugujemy akcjÄ™ wylogowywania: najpierw kasujemy sesjÄ™, a później tworzymy sesjÄ™ goÅ›cia.
Gdy nie udało się załadować danych sesji, wykonujemy takie akcje:
}else{ $session -> session_id = ''; do_auth(); if(defined('LOGIN_REQUIRED')){ form_request(); die(); } $session -> guest_session(); }
Krótko: to, co powyżej, tyle że bez obsÅ‚ugi wylogowywania i domyÅ›lnym tworzeniem sesji goÅ›cia.
To samo wykonamy też, gdy sesja w ogóle nie istnieje. Wiadomo, że skoro formularz logowania może wyÅ›wietlić siÄ™ bez sesji, również w takim przypadku musimy wziąć pod uwagÄ™ możliwość autoryzacji.
do_auth(); if(defined('LOGIN_REQUIRED')){ form_request(); die(); } $session -> guest_session(); } ?>
I... to w zasadzie tyle.
Do przetestowania naszego majstersztyksu potrzebujemy jeszcze trochÄ™ kodu PHP: zestawu dodatkowych funkcji (połączenie z bazÄ…, wyÅ›wietlanie formularza logowania, oraz błędu, a także prezentacja nagÅ‚ówka w stylu "Witaj goÅ›ciu"/"Witaj, jesteÅ› zalogowany jako XXX"). Oto plik functions.php:
<?php function form_request(){ echo <<<EOF <html> <head> <title>Zaloguj siÄ™</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2"> </head> <body> <center>Zaloguj siÄ™</center> <form method="post" action="index.php?auth=login"> Twój login: <input type="text" name="login"/><br/> Twoje hasÅ‚o: <input type="text" name="password"/><br/> <input type="submit" value="Loguj!"/> </form> </body> </html> EOF; } // end form_request(); function error($komunikat){ echo <<<EOF <html> <head> <title>BÅ‚±d autoryzacji</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2"> </head> <body> <center>BÅ‚±d</center> Podczas autoryzacji wyst±piÅ‚ bÅ‚±d: {$komunikat} </body> </html> EOF; } // end error(); function db_connect(){ mysql_connect('localhost', 'root', ''); mysql_select_db('artykuly'); } // end db_connect(); function print_header(){ global $session; if($session -> type == GUEST_S){ echo 'Witaj, go¶ciu<br/>'; }else{ echo 'Witaj, jeste¶ zalogowany jako '.$session -> userdata['NAME'].' (<a href="index.php?auth=logout">Wyloguj</a>)<br/>'; } } // end print_header(); function db_close(){ mysql_close(); } // end db_close(); ?>
Całość natomiast przetestujemy na pięciu stronach: INDEX, STRONA1, STRONA2, STRONA3 i STRONA4. Aby wejść na dwie ostatnie, będziemy się musieli zalogować, w przeciwnym razie dostaniemy formularz do logowania, a nie ich zawartość. Na początek plik index.php:
<?php require('functions.php'); db_connect(); require('sessions.php'); require('auth.php'); print_header(); db_close(); ?> Witaj w INDEX <ul> <li><a href="s1.php">Strona 1</a></li> <li><a href="s2.php">Strona 2</a></li> <li><a href="s3.php">Strona 3 (wymaga autoryzacji)</a></li> <li><a href="s4.php">Strona 4 (wymaga autoryzacji)</a></li> </ul>
s1.php:
<?php require('functions.php'); db_connect(); require('sessions.php'); require('auth.php'); print_header(); db_close(); ?> Witaj w STRONA 1 <ul> <li><a href="index.php">INDEX</a></li> <li><a href="s2.php">Strona 2</a></li> <li><a href="s3.php">Strona 3 (wymaga autoryzacji)</a></li> <li><a href="s4.php">Strona 4 (wymaga autoryzacji)</a></li> </ul>
s2.php:
<?php require('functions.php'); db_connect(); require('sessions.php'); require('auth.php'); print_header(); db_close(); ?> Witaj w STRONA 2 <ul> <li><a href="index.php">INDEX</a></li> <li><a href="s1.php">Strona 1</a></li> <li><a href="s3.php">Strona 3 (wymaga autoryzacji)</a></li> <li><a href="s4.php">Strona 4 (wymaga autoryzacji)</a></li> </ul>
s3.php:
<?php define('LOGIN_REQUIRED', 1); require('functions.php'); db_connect(); require('sessions.php'); require('auth.php'); print_header(); db_close(); ?> Witaj w STRONA 3 <ul> <li><a href="index.php">INDEX</a></li> <li><a href="s1.php">Strona 1</a></li> <li><a href="s2.php">Strona 2</a></li> <li><a href="s4.php">Strona 4 (wymaga autoryzacji)</a></li> </ul>
s4.php:
<?php define('LOGIN_REQUIRED', 1); require('functions.php'); db_connect(); require('sessions.php'); require('auth.php'); print_header(); db_close(); ?> Witaj w STRONA 4 <ul> <li><a href="index.php">INDEX</a></li> <li><a href="s1.php">Strona 1</a></li> <li><a href="s2.php">Strona 2</a></li> <li><a href="s3.php">Strona 3 (wymaga autoryzacji)</a></li> </ul>
Przypominam, że aby wymusić konieczność zalogowania siÄ™ na strony 3 i 4, na samym poczÄ…tku plików do ich obsÅ‚ugi zdefiniowaÅ‚em stałą LOGIN_REQUIRED.
Gratulacje, możesz teraz uruchomić skrypt i przetestować go! W bazie jest już zdefiniowany przykładowy użytkownik: "luser", a jego hasło to "ppp".
Sesje i autoryzacja to rozlegÅ‚y temat. Gdyby opisać go dokÅ‚adnie w tym artykule, prawdopodobnie nie starczyÅ‚oby na to miejsca w bazie :). Ponadto, zazwyczaj w tym wypadku najlepiej jest stworzyć system stosowny do naszych potrzeb. Potrzebujemy grup? Dodajemy grupy. A może każdemu z użytkowników bÄ™dzie można osobno definiować uprawnienia? Również nic trudnego. Wystarczy tylko chcieć.
Specjalnie nie rozbudowaÅ‚em powyższego skryptu do rozmiarów i możliwoÅ›ci systemów znanych z phpBB, czy InvisionBoard, byÅ› mógÅ‚ to uczynić sam, w ramach praktyki. Jednak mogÄ™ Å›miaÅ‚o przypuszczać, że niezbyt bÄ™dziesz chciaÅ‚ zgłębiać tajniki kodu ww. systemów, by znaleźć coÅ› interesujÄ…cego. Dlatego też co ciekawsze pomysÅ‚y opisaÅ‚em poniżej.
Autor: Tomasz "Zyx" Jędrzejewski, www.zyxist.com
Waszym zdaniem:
Nikt jeszcze nie dodał swojego komentarza. Możesz być pierwszy!