{"id":1203,"date":"2025-02-17T13:13:35","date_gmt":"2025-02-17T12:13:35","guid":{"rendered":"https:\/\/piotrgabriel.pl\/wiki\/?p=1203"},"modified":"2025-02-17T13:13:35","modified_gmt":"2025-02-17T12:13:35","slug":"sesje-w-php-jak-zabezpieczyc-strone-www-przed-nieautoryzowanym-dostepem","status":"publish","type":"post","link":"https:\/\/piotrgabriel.pl\/wiki\/sesje-w-php-jak-zabezpieczyc-strone-www-przed-nieautoryzowanym-dostepem\/","title":{"rendered":"Sesje w PHP \u2013 Jak zabezpieczy\u0107 stron\u0119 WWW przed nieautoryzowanym dost\u0119pem"},"content":{"rendered":"<p data-pm-slice=\"1 1 []\">Chcesz nauczy\u0107 si\u0119, jak w praktyce zabezpieczy\u0107 stron\u0119 internetow\u0105 przed nieautoryzowanym dost\u0119pem? Mamy tutaj proste rozwi\u0105zanie, w postaci kr\u00f3tkiego poradnika a mowa o <strong>mechanizmie sesji w PHP<\/strong>. Dzi\u0119ki przyk\u0142adowi, jaki tutaj opisa\u0142em, dowiesz si\u0119, czym s\u0105 sesje w PHP, dlaczego s\u0105 wa\u017cne i jak poprawnie je zaimplementowa\u0107 w swoim kodzie.<\/p>\n<p><strong>Sesje w PHP<\/strong> to mechanizm, kt\u00f3ry pozwala przechowywa\u0107 dane u\u017cytkownika pomi\u0119dzy \u017c\u0105daniami HTTP. Dzi\u0119ki nim mo\u017cna np. zapami\u0119ta\u0107, \u017ce kto\u015b jest zalogowany i nie wymaga ponownego wpisywania has\u0142a na ka\u017cdej podstronie.<\/p>\n<p>Zalety sesji w PHP:<\/p>\n<ul data-spread=\"false\">\n<li><strong>Bezpiecze\u0144stwo<\/strong> \u2013 sesje s\u0105 przechowywane po stronie serwera, co utrudnia ich przechwycenie przez atakuj\u0105cych.<\/li>\n<li><strong>Personalizacja<\/strong> \u2013 pozwalaj\u0105 na dostosowanie zawarto\u015bci strony do konkretnego u\u017cytkownika.<\/li>\n<li><strong>\u0141atwo\u015b\u0107 obs\u0142ugi<\/strong> \u2013 PHP zapewnia wbudowane funkcje do zarz\u0105dzania sesjami, co u\u0142atwia ich implementacj\u0119.<\/li>\n<\/ul>\n<p>Dobre praktyki zwi\u0105zane z sesjami:<\/p>\n<ul data-spread=\"false\">\n<li><strong>Unikaj przechowywania wra\u017cliwych danych<\/strong> w sesji (np. hase\u0142, numer\u00f3w kart kredytowych).<\/li>\n<li><strong>Regeneruj identyfikator sesji<\/strong> po zalogowaniu, aby zapobiec atakom typu session fixation.<\/li>\n<li><strong>Ustaw czas wa\u017cno\u015bci sesji<\/strong> i usuwaj je po wylogowaniu u\u017cytkownika.<\/li>\n<li><strong>U\u017cywaj tylko HTTPS<\/strong>, aby zabezpieczy\u0107 dane sesji przed przechwyceniem.<\/li>\n<\/ul>\n<p>Stw\u00f3rzmy wi\u0119c system logowania, zabezpieczmy has\u0142a u\u017cytkownik\u00f3w oraz zadbajmy o przekierowania w przypadku pr\u00f3by wej\u015bcia na stron\u0119 bez logowania (wej\u015bcia nieautoryzowane, stanowi\u0105ce potencjalne zagro\u017cenie).<\/p>\n<h2 data-pm-slice=\"1 1 []\">1. Tworzenie bazy danych i tabeli u\u017cytkownik\u00f3w<\/h2>\n<p data-pm-slice=\"1 1 []\">Zacznijmy od utworzenia bazy danych i tabeli u\u017cytkownik\u00f3w. Wykorzystamy MySQL oraz bezpieczne przechowywanie hase\u0142 za pomoc\u0105 funkcji <code>password_hash()<\/code>, kt\u00f3ra s\u0142u\u017cy do bezpiecznego hashowania hase\u0142 u\u017cytkownik\u00f3w.<\/p>\n<p data-pm-slice=\"1 1 []\"><code>password_hash()<\/code>dzia\u0142a w taki spos\u00f3b, \u017ce z<strong>amienia podane has\u0142o na unikalny ci\u0105g znak\u00f3w (hash)<\/strong>, korzystaj\u0105c z algorytmu bcrypt lub innego dost\u0119pnego w PHP. Dzi\u0119ki temu zapisane has\u0142o jest niemo\u017cliwe do odczytania w bazie danych.<\/p>\n<p data-pm-slice=\"1 1 []\">Podczas logowania por\u00f3wnujemy wprowadzone has\u0142o u\u017cytkownika z jego zapisanym odpowiednikiem w bazie przy u\u017cyciu funkcji <code>password_verify()<\/code>, co pozwala na weryfikacj\u0119 poprawno\u015bci has\u0142a bez jego bezpo\u015bredniego przechowywania.<\/p>\n<h3>Tworzenie bazy danych i tabeli u\u017cytkownik\u00f3w<\/h3>\n<p><code>CREATE DATABASE secure_login;<\/code><\/p>\n<p><code>USE secure_login;<\/code><\/p>\n<p><code>CREATE TABLE users (<\/code><br \/>\n<code>id INT AUTO_INCREMENT PRIMARY KEY,<\/code><br \/>\n<code>username VARCHAR(50) NOT NULL UNIQUE,<\/code><br \/>\n<code>password VARCHAR(255) NOT NULL<\/code><br \/>\n<code>);<\/code><\/p>\n<p data-start=\"0\" data-end=\"382\">Pewnie zastanawiasz si\u0119, czym jest zapis <code data-start=\"0\" data-end=\"19\">USE secure_login;<\/code> to polecenie SQL, kt\u00f3re wskazuje serwerowi MySQL, \u017ce wszystkie kolejne operacje na bazie danych maj\u0105 by\u0107 wykonywane w kontek\u015bcie bazy <code data-start=\"154\" data-end=\"168\">secure_login<\/code>. Innymi s\u0142owy, prze\u0142\u0105cza aktywn\u0105 baz\u0119 danych na <code data-start=\"217\" data-end=\"231\">secure_login<\/code>, co oznacza, \u017ce ka\u017cda nast\u0119pna komenda, taka jak <code data-start=\"281\" data-end=\"295\">CREATE TABLE<\/code> czy <code data-start=\"300\" data-end=\"308\">SELECT<\/code>, b\u0119dzie odnosi\u0107 si\u0119 w\u0142a\u015bnie do tej bazy, o ile nie zostanie podana inna.<\/p>\n<p data-start=\"384\" data-end=\"513\" data-is-last-node=\"\">Bez tego polecenia, je\u015bli mamy wiele baz danych na serwerze, MySQL nie wiedzia\u0142by, w kt\u00f3rej bazie powinien wykona\u0107 dan\u0105 operacj\u0119.<\/p>\n<p data-pm-slice=\"1 1 []\">Teraz dodajmy u\u017cytkownika <code>admin<\/code> z has\u0142em <code>admin123<\/code>, zabezpieczonym przy u\u017cyciu <code>password_hash()<\/code>.<\/p>\n<h3>Dodanie u\u017cytkownika admin<\/h3>\n<p data-start=\"0\" data-end=\"92\">Dodawanie u\u017cytkownika przez PHP zamiast r\u0119cznie w bazie danych jest istotne z kilku powod\u00f3w:<\/p>\n<ol data-start=\"94\" data-end=\"1177\">\n<li data-start=\"94\" data-end=\"385\">\n<p data-start=\"97\" data-end=\"385\"><strong data-start=\"97\" data-end=\"115\">Bezpiecze\u0144stwo<\/strong> \u2013 Je\u015bli dodasz u\u017cytkownika przez PHP, mo\u017cesz u\u017cy\u0107 <code data-start=\"166\" data-end=\"183\">password_hash()<\/code>, co zapewnia bezpieczne hashowanie has\u0142a. Wpisanie has\u0142a bezpo\u015brednio do bazy danych bez hashowania oznacza\u0142oby, \u017ce jest ono przechowywane w postaci jawnej, co jest powa\u017cnym zagro\u017ceniem bezpiecze\u0144stwa.<\/p>\n<\/li>\n<li data-start=\"387\" data-end=\"603\">\n<p data-start=\"390\" data-end=\"603\"><strong data-start=\"390\" data-end=\"407\">Automatyzacja<\/strong> \u2013 W prawdziwych systemach u\u017cytkownicy rejestruj\u0105 si\u0119 sami, a aplikacja dodaje ich do bazy dynamicznie. R\u0119czne dodawanie u\u017cytkownik\u00f3w nie jest praktyczne, zw\u0142aszcza gdy liczba u\u017cytkownik\u00f3w ro\u015bnie.<\/p>\n<\/li>\n<li data-start=\"605\" data-end=\"807\">\n<p data-start=\"608\" data-end=\"807\"><strong data-start=\"608\" data-end=\"633\">Ochrona przed b\u0142\u0119dami<\/strong> \u2013 Podczas r\u0119cznego dodawania mo\u017cna przypadkowo wpisa\u0107 b\u0142\u0119dne dane lub u\u017cy\u0107 nieprawid\u0142owego formatu. Kod PHP dba o to, by dane by\u0142y poprawne i zgodne z za\u0142o\u017ceniami aplikacji.<\/p>\n<\/li>\n<li data-start=\"809\" data-end=\"969\">\n<p data-start=\"812\" data-end=\"969\"><strong data-start=\"812\" data-end=\"835\">\u0141atwo\u015b\u0107 zarz\u0105dzania<\/strong> \u2013 U\u017cycie PHP do dodawania u\u017cytkownik\u00f3w oznacza, \u017ce mo\u017cna \u0142atwo rozbudowa\u0107 system o panel administratora do zarz\u0105dzania u\u017cytkownikami.<\/p>\n<\/li>\n<\/ol>\n<p><code>&lt;?php<\/code><br \/>\n<code>$servername = \"localhost\";<\/code><br \/>\n<code>$username = \"root\";<\/code><br \/>\n<code>$password = \"\";<\/code><br \/>\n<code>$dbname = \"secure_login\";<\/code><\/p>\n<p><code>$conn = new mysqli($servername, $username, $password, $dbname);<\/code><\/p>\n<p><code>if ($conn-&gt;connect_error) {<\/code><br \/>\n<code>die(\"B\u0142\u0105d po\u0142\u0105czenia: \" . $conn-&gt;connect_error);<\/code><br \/>\n<code>}<\/code><\/p>\n<p><code>$hashed_password = password_hash(\"admin123\", PASSWORD_DEFAULT);<\/code><br \/>\n<code>$sql = \"INSERT INTO users (username, password) VALUES ('admin', '$hashed_password')\";<\/code><\/p>\n<p><code>if ($conn-&gt;query($sql) === TRUE) {<\/code><br \/>\n<code>echo \"U\u017cytkownik admin zosta\u0142 dodany.\";<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"B\u0142\u0105d: \" . $conn-&gt;error;<\/code><br \/>\n<code>}<\/code><\/p>\n<p><code>$conn-&gt;close();<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<p>Po wywo\u0142aniu skryptu, w bazie danych mo\u017cemy sprawdzi\u0107, \u017ce u\u017cytkownik zosta\u0142 dodany, oraz jego has\u0142o (dla przyk\u0142adu admin123) zosta\u0142o zahashowane<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1204 aligncenter\" src=\"https:\/\/piotrgabriel.pl\/wiki\/wp-content\/uploads\/2025\/02\/hashowanie-hasla-w-bazie-danych.png\" alt=\"\" width=\"1036\" height=\"250\" title=\"\" srcset=\"https:\/\/piotrgabriel.pl\/wiki\/wp-content\/uploads\/2025\/02\/hashowanie-hasla-w-bazie-danych.png 1036w, https:\/\/piotrgabriel.pl\/wiki\/wp-content\/uploads\/2025\/02\/hashowanie-hasla-w-bazie-danych-300x72.png 300w, https:\/\/piotrgabriel.pl\/wiki\/wp-content\/uploads\/2025\/02\/hashowanie-hasla-w-bazie-danych-1024x247.png 1024w, https:\/\/piotrgabriel.pl\/wiki\/wp-content\/uploads\/2025\/02\/hashowanie-hasla-w-bazie-danych-768x185.png 768w, https:\/\/piotrgabriel.pl\/wiki\/wp-content\/uploads\/2025\/02\/hashowanie-hasla-w-bazie-danych-820x198.png 820w\" sizes=\"auto, (max-width: 1036px) 100vw, 1036px\" \/><\/p>\n<h2 data-pm-slice=\"1 1 []\">2. Tworzenie formularza logowania (login.php)<\/h2>\n<p>Stworzymy prosty formularz logowania, kt\u00f3ry przesy\u0142a dane metod\u0105 POST do skryptu <code>login.php<\/code>.<\/p>\n<p><code>&lt;!DOCTYPE html&gt;<\/code><br \/>\n<code>&lt;html lang=\"pl\"&gt;<\/code><br \/>\n<code>&lt;head&gt;<\/code><br \/>\n<code>&lt;meta charset=\"UTF-8\"&gt;<\/code><br \/>\n<code>&lt;title&gt;Logowanie&lt;\/title&gt;<\/code><br \/>\n<code>&lt;\/head&gt;<\/code><br \/>\n<code>&lt;body&gt;<\/code><br \/>\n<code>&lt;h2&gt;Logowanie&lt;\/h2&gt;<\/code><br \/>\n<code>&lt;form action=\"login.php\" method=\"POST\"&gt;<\/code><br \/>\n<code>&lt;label for=\"username\"&gt;Login:&lt;\/label&gt;<\/code><br \/>\n<code>&lt;input type=\"text\" name=\"username\" required&gt;<\/code><br \/>\n<code>&lt;br&gt;<\/code><br \/>\n<code>&lt;label for=\"password\"&gt;Has\u0142o:&lt;\/label&gt;<\/code><br \/>\n<code>&lt;input type=\"password\" name=\"password\" required&gt;<\/code><br \/>\n<code>&lt;br&gt;<\/code><br \/>\n<code>&lt;button type=\"submit\"&gt;Zaloguj&lt;\/button&gt;<\/code><br \/>\n<code>&lt;\/form&gt;<\/code><br \/>\n<code>&lt;\/body&gt;<\/code><br \/>\n<code>&lt;\/html&gt;<\/code><\/p>\n<h2 data-pm-slice=\"1 1 []\">3. Obs\u0142uga logowania i tworzenie sesji (login.php)<\/h2>\n<p>Teraz napiszemy kod do weryfikacji logowania i inicjalizacji sesji u\u017cytkownika.<\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>session_start();<\/code><br \/>\n<code>$servername = \"localhost\";<\/code><br \/>\n<code>$username = \"root\";<\/code><br \/>\n<code>$password = \"\";<\/code><br \/>\n<code>$dbname = \"secure_login\";<\/code><\/p>\n<p><code>$conn = new mysqli($servername, $username, $password, $dbname);<\/code><\/p>\n<p><code>if ($conn-&gt;connect_error) {<\/code><br \/>\n<code>die(\"B\u0142\u0105d po\u0142\u0105czenia: \" . $conn-&gt;connect_error);<\/code><br \/>\n<code>}<\/code><\/p>\n<p><code>if ($_SERVER[\"REQUEST_METHOD\"] == \"POST\") {<\/code><br \/>\n<code>$username = $_POST['username'];<\/code><br \/>\n<code>$password = $_POST['password'];<\/code><\/p>\n<p><code>$stmt = $conn-&gt;prepare(\"SELECT id, password FROM users WHERE username = ?\");<\/code><br \/>\n<code>$stmt-&gt;bind_param(\"s\", $username);<\/code><br \/>\n<code>$stmt-&gt;execute();<\/code><br \/>\n<code>$stmt-&gt;store_result();<\/code><br \/>\n<code>$stmt-&gt;bind_result($id, $hashed_password);<\/code><br \/>\n<code>$stmt-&gt;fetch();<\/code><\/p>\n<p><code>if ($stmt-&gt;num_rows &gt; 0 &amp;&amp; password_verify($password, $hashed_password)) {<\/code><br \/>\n<code>$_SESSION['user_id'] = $id;<\/code><br \/>\n<code>$_SESSION['username'] = $username;<\/code><br \/>\n<code>header(\"Location: index.php\");<\/code><br \/>\n<code>exit();<\/code><br \/>\n<code>} else {<\/code><br \/>\n<code>echo \"Nieprawid\u0142owy login lub has\u0142o.\";<\/code><br \/>\n<code>}<\/code><\/p>\n<p><code>$stmt-&gt;close();<\/code><br \/>\n<code>}<\/code><br \/>\n<code>$conn-&gt;close();<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<p data-start=\"0\" data-end=\"31\">Oto wyja\u015bnienie dzia\u0142ania kodu:<\/p>\n<ol data-start=\"33\" data-end=\"1900\">\n<li data-start=\"33\" data-end=\"194\">\n<p data-start=\"36\" data-end=\"194\"><strong data-start=\"36\" data-end=\"59\">Inicjalizacja sesji<\/strong> \u2013 <code data-start=\"62\" data-end=\"80\">session_start();<\/code> uruchamia mechanizm sesji, co pozwala na przechowywanie informacji o u\u017cytkowniku mi\u0119dzy kolejnymi \u017c\u0105daniami HTTP.<\/p>\n<\/li>\n<li data-start=\"196\" data-end=\"518\">\n<p data-start=\"199\" data-end=\"226\"><strong data-start=\"199\" data-end=\"225\">\u0141\u0105czenie z baz\u0105 danych<\/strong>:<\/p>\n<ul data-start=\"230\" data-end=\"518\">\n<li data-start=\"230\" data-end=\"319\">Ustawiane s\u0105 parametry po\u0142\u0105czenia (<code data-start=\"267\" data-end=\"280\">$servername<\/code>, <code data-start=\"282\" data-end=\"293\">$username<\/code>, <code data-start=\"295\" data-end=\"306\">$password<\/code>, <code data-start=\"308\" data-end=\"317\">$dbname<\/code>).<\/li>\n<li data-start=\"323\" data-end=\"405\">Tworzony jest nowy obiekt <code data-start=\"351\" data-end=\"359\">mysqli<\/code>, kt\u00f3ry odpowiada za po\u0142\u0105czenie z baz\u0105 danych.<\/li>\n<li data-start=\"409\" data-end=\"518\">Je\u015bli wyst\u0105pi b\u0142\u0105d po\u0142\u0105czenia, skrypt zwraca komunikat o b\u0142\u0119dzie i zatrzymuje dalsze wykonywanie (<code data-start=\"509\" data-end=\"516\">die()<\/code>).<\/li>\n<\/ul>\n<\/li>\n<li data-start=\"520\" data-end=\"739\">\n<p data-start=\"523\" data-end=\"548\"><strong data-start=\"523\" data-end=\"547\">Obs\u0142uga \u017c\u0105dania POST<\/strong>:<\/p>\n<ul data-start=\"552\" data-end=\"739\">\n<li data-start=\"552\" data-end=\"656\">Sprawdzane jest, czy dane zosta\u0142y przes\u0142ane metod\u0105 POST (<code data-start=\"611\" data-end=\"654\">if ($_SERVER[\"REQUEST_METHOD\"] == \"POST\")<\/code>).<\/li>\n<li data-start=\"660\" data-end=\"739\">Pobierane s\u0105 dane z formularza (<code data-start=\"694\" data-end=\"714\">$_POST['username']<\/code> i <code data-start=\"717\" data-end=\"737\">$_POST['password']<\/code>).<\/li>\n<\/ul>\n<\/li>\n<li data-start=\"741\" data-end=\"1323\">\n<p data-start=\"744\" data-end=\"773\"><strong data-start=\"744\" data-end=\"772\">Zapytanie do bazy danych<\/strong>:<\/p>\n<ul data-start=\"777\" data-end=\"1323\">\n<li data-start=\"777\" data-end=\"943\">Tworzone jest przygotowane zapytanie SQL do wyszukania u\u017cytkownika o podanej nazwie (<code data-start=\"864\" data-end=\"941\">$stmt = $conn-&gt;prepare(\"SELECT id, password FROM users WHERE username = ?\")<\/code>).<\/li>\n<li data-start=\"947\" data-end=\"1051\"><code data-start=\"949\" data-end=\"978\">bind_param(\"s\", $username);<\/code> wi\u0105\u017ce podany login z parametrem SQL, zabezpieczaj\u0105c przed SQL Injection.<\/li>\n<li data-start=\"1055\" data-end=\"1089\"><code data-start=\"1057\" data-end=\"1069\">execute();<\/code> wykonuje zapytanie.<\/li>\n<li data-start=\"1093\" data-end=\"1193\"><code data-start=\"1095\" data-end=\"1112\">store_result();<\/code> przechowuje wynik zapytania, co pozwala na sprawdzenie, czy u\u017cytkownik istnieje.<\/li>\n<li data-start=\"1197\" data-end=\"1278\"><code data-start=\"1199\" data-end=\"1236\">bind_result($id, $hashed_password);<\/code> przypisuje wyniki zapytania do zmiennych.<\/li>\n<li data-start=\"1282\" data-end=\"1323\"><code data-start=\"1284\" data-end=\"1294\">fetch();<\/code> pobiera wynik z bazy danych.<\/li>\n<\/ul>\n<\/li>\n<li data-start=\"1325\" data-end=\"1767\">\n<p data-start=\"1328\" data-end=\"1350\"><strong data-start=\"1328\" data-end=\"1349\">Weryfikacja has\u0142a<\/strong>:<\/p>\n<ul data-start=\"1354\" data-end=\"1767\">\n<li data-start=\"1354\" data-end=\"1477\"><code data-start=\"1356\" data-end=\"1403\">password_verify($password, $hashed_password);<\/code> por\u00f3wnuje has\u0142o wpisane przez u\u017cytkownika z zaszyfrowanym has\u0142em w bazie.<\/li>\n<li data-start=\"1481\" data-end=\"1651\">Je\u015bli has\u0142o jest poprawne:\n<ul data-start=\"1515\" data-end=\"1651\">\n<li data-start=\"1515\" data-end=\"1595\">Tworzone s\u0105 zmienne sesyjne (<code data-start=\"1546\" data-end=\"1568\">$_SESSION['user_id']<\/code>, <code data-start=\"1570\" data-end=\"1593\">$_SESSION['username']<\/code>).<\/li>\n<li data-start=\"1601\" data-end=\"1651\">U\u017cytkownik zostaje przekierowany do <code data-start=\"1639\" data-end=\"1650\">index.php<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li data-start=\"1655\" data-end=\"1767\">Je\u015bli has\u0142o jest b\u0142\u0119dne lub u\u017cytkownik nie istnieje, wy\u015bwietla si\u0119 komunikat <code data-start=\"1734\" data-end=\"1766\">Nieprawid\u0142owy login lub has\u0142o.<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li data-start=\"1769\" data-end=\"1900\">\n<p data-start=\"1772\" data-end=\"1797\"><strong data-start=\"1772\" data-end=\"1796\">Zamykanie po\u0142\u0105czenia<\/strong>:<\/p>\n<ul data-start=\"1801\" data-end=\"1900\">\n<li data-start=\"1801\" data-end=\"1851\"><code data-start=\"1803\" data-end=\"1820\">$stmt-&gt;close();<\/code> zamyka przygotowane zapytanie.<\/li>\n<li data-start=\"1855\" data-end=\"1900\"><code data-start=\"1857\" data-end=\"1874\">$conn-&gt;close();<\/code> zamyka po\u0142\u0105czenie z baz\u0105.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p data-start=\"1902\" data-end=\"2036\" data-is-last-node=\"\">Dzi\u0119ki temu kodowi u\u017cytkownik mo\u017ce si\u0119 zalogowa\u0107, a jego dane sesyjne b\u0119d\u0105 przechowywane, umo\u017cliwiaj\u0105c mu dost\u0119p do chronionych stron.<\/p>\n<h2 data-pm-slice=\"1 1 []\">4. Zabezpieczenie strony g\u0142\u00f3wnej (index.php)<\/h2>\n<p>Je\u015bli u\u017cytkownik nie jest zalogowany, przekierujemy go na stron\u0119 logowania.<\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>session_start();<\/code><br \/>\n<code>if (!isset($_SESSION['user_id'])) {<\/code><br \/>\n<code>header(\"Location: login.php\");<\/code><br \/>\n<code>exit();<\/code><br \/>\n<code>}<\/code><br \/>\n<code>?&gt;<\/code><br \/>\n<code>&lt;!DOCTYPE html&gt;<\/code><br \/>\n<code>&lt;html lang=\"pl\"&gt;<\/code><br \/>\n<code>&lt;head&gt;<\/code><br \/>\n<code>&lt;meta charset=\"UTF-8\"&gt;<\/code><br \/>\n<code>&lt;title&gt;Panel u\u017cytkownika&lt;\/title&gt;<\/code><br \/>\n<code>&lt;\/head&gt;<\/code><br \/>\n<code>&lt;body&gt;<\/code><br \/>\n<code>&lt;h2&gt;Witaj, &lt;?php echo htmlspecialchars($_SESSION['username']); ?&gt;!&lt;\/h2&gt;<\/code><br \/>\n<code>&lt;a href=\"logout.php\"&gt;Wyloguj&lt;\/a&gt;<\/code><br \/>\n<code>&lt;\/body&gt;<\/code><br \/>\n<code>&lt;\/html&gt;<\/code><\/p>\n<h2 data-pm-slice=\"1 1 []\">5. Wylogowanie u\u017cytkownika (logout.php)<\/h2>\n<p>Aby umo\u017cliwi\u0107 u\u017cytkownikowi wylogowanie, dodajmy skrypt <code>logout.php<\/code>, kt\u00f3ry usunie dane sesji.<\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>session_start();<\/code><br \/>\n<code>session_unset();<\/code><br \/>\n<code>session_destroy();<\/code><br \/>\n<code>header(\"Location: login.php\");<\/code><br \/>\n<code>exit();<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<p data-start=\"0\" data-end=\"153\">Ten kod realizuje funkcj\u0119 wylogowania u\u017cytkownika poprzez usuni\u0119cie jego sesji i przekierowanie go na stron\u0119 logowania. Oto jego dzia\u0142anie krok po kroku:<\/p>\n<ol data-start=\"155\" data-end=\"864\">\n<li data-start=\"155\" data-end=\"261\">\n<p data-start=\"158\" data-end=\"261\"><strong data-start=\"158\" data-end=\"180\"><code data-start=\"160\" data-end=\"178\">session_start();<\/code><\/strong> \u2013 Rozpoczyna lub wznawia sesj\u0119, co jest konieczne do manipulowania danymi sesji.<\/p>\n<\/li>\n<li data-start=\"263\" data-end=\"390\">\n<p data-start=\"266\" data-end=\"390\"><strong data-start=\"266\" data-end=\"288\"><code data-start=\"268\" data-end=\"286\">session_unset();<\/code><\/strong> \u2013 Usuwa wszystkie zmienne sesyjne. Nie ko\u0144czy samej sesji, ale czy\u015bci wszystkie zapisane w niej dane.<\/p>\n<\/li>\n<li data-start=\"392\" data-end=\"523\">\n<p data-start=\"395\" data-end=\"523\"><strong data-start=\"395\" data-end=\"419\"><code data-start=\"397\" data-end=\"417\">session_destroy();<\/code><\/strong> \u2013 Niszczy ca\u0142\u0105 sesj\u0119, usuwaj\u0105c jej identyfikator oraz wszystkie zwi\u0105zane z ni\u0105 dane po stronie serwera.<\/p>\n<\/li>\n<li data-start=\"525\" data-end=\"730\">\n<p data-start=\"528\" data-end=\"730\"><strong data-start=\"528\" data-end=\"564\"><code data-start=\"530\" data-end=\"562\">header(\"Location: login.php\");<\/code><\/strong> \u2013 Przekierowuje u\u017cytkownika na stron\u0119 logowania po zniszczeniu sesji, co oznacza, \u017ce u\u017cytkownik musi zalogowa\u0107 si\u0119 ponownie, aby uzyska\u0107 dost\u0119p do chronionych stron.<\/p>\n<\/li>\n<li data-start=\"732\" data-end=\"864\">\n<p data-start=\"735\" data-end=\"864\"><strong data-start=\"735\" data-end=\"748\"><code data-start=\"737\" data-end=\"746\">exit();<\/code><\/strong> \u2013 Zapewnia, \u017ce skrypt zako\u0144czy dzia\u0142anie natychmiast po przekierowaniu, uniemo\u017cliwiaj\u0105c wykonanie dodatkowego kodu.<\/p>\n<\/li>\n<\/ol>\n<p data-start=\"866\" data-end=\"992\" data-is-last-node=\"\">To proste, ale skuteczne rozwi\u0105zanie zapewnia, \u017ce po wylogowaniu u\u017cytkownik traci dost\u0119p do stron wymagaj\u0105cych aktywnej sesji.<\/p>\n<h2 data-pm-slice=\"1 1 []\">Podsumujmy wi\u0119c ca\u0142y mechanizm obs\u0142ugi Sesji w PHP<\/h2>\n<p>Stworzyli\u015bmy prosty i bezpieczny system logowania w PHP z wykorzystaniem MySQL. Kluczowe kroki:<\/p>\n<ul data-spread=\"false\">\n<li>Tworzenie bazy danych i tabeli u\u017cytkownik\u00f3w.<\/li>\n<li>Zabezpieczenie hase\u0142 funkcj\u0105 <code>password_hash()<\/code>.<\/li>\n<li>Tworzenie formularza logowania i weryfikacja danych.<\/li>\n<li>Implementacja sesji w PHP.<\/li>\n<li>Zabezpieczenie stron przed nieautoryzowanym dost\u0119pem.<\/li>\n<li>Mo\u017cliwo\u015b\u0107 wylogowania u\u017cytkownika.<\/li>\n<\/ul>\n<p data-pm-slice=\"1 1 []\">Teraz masz gotowy szkielet do rozbudowy systemu logowania w Twojej aplikacji!<\/p>\n<h3>Jak zabezpieczy\u0107 kolejne pliki mechanizmem sesji?<\/h3>\n<p>Aby zabezpieczy\u0107 inne strony, wystarczy doda\u0107 na pocz\u0105tku ka\u017cdego pliku nast\u0119puj\u0105cy kod:<\/p>\n<p><code>&lt;?php<\/code><br \/>\n<code>session_start();<\/code><br \/>\n<code>if (!isset($_SESSION['user_id'])) {<\/code><br \/>\n<code>header(\"Location: login.php\");<\/code><br \/>\n<code>exit();<\/code><br \/>\n<code>}<\/code><br \/>\n<code>?&gt;<\/code><\/p>\n<p data-pm-slice=\"1 1 []\">Dzi\u0119ki temu ka\u017cda strona b\u0119dzie sprawdza\u0107, czy u\u017cytkownik jest zalogowany. Je\u015bli nie \u2013 zostanie przekierowany na stron\u0119 logowania.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Chcesz nauczy\u0107 si\u0119, jak w praktyce zabezpieczy\u0107 stron\u0119 internetow\u0105 przed nieautoryzowanym dost\u0119pem? Mamy tutaj proste rozwi\u0105zanie, w postaci kr\u00f3tkiego poradnika a mowa o mechanizmie sesji w PHP. Dzi\u0119ki przyk\u0142adowi, jaki tutaj opisa\u0142em, dowiesz si\u0119, czym s\u0105 sesje w PHP, dlaczego [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1205,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48,244],"tags":[24,67],"class_list":["post-1203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bazy-danych","category-php","tag-mysql","tag-php"],"_links":{"self":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts\/1203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/comments?post=1203"}],"version-history":[{"count":1,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts\/1203\/revisions"}],"predecessor-version":[{"id":1206,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/posts\/1203\/revisions\/1206"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/media\/1205"}],"wp:attachment":[{"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/media?parent=1203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/categories?post=1203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/piotrgabriel.pl\/wiki\/wp-json\/wp\/v2\/tags?post=1203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}