Lekcja 16. Ochrona stron przed niezalogowanymi użytkownikami
Trudny / egzaminacyjnyPo co się tego uczymy?
Bez tej lekcji każdy — zalogowany czy nie — mógłby wejść bezpośrednio na adres panel.php albo koszyk.php, wpisując go ręcznie w przeglądarce. Ochrona stron to bardzo prosty, ale absolutnie niezbędny mechanizm bezpieczeństwa każdej aplikacji z kontami użytkowników.
Teoria
Sama możliwość zalogowania się to nie wszystko — trzeba jeszcze ZABLOKOWAĆ dostęp do stron, które powinny widzieć tylko zalogowani użytkownicy (panel konta, historia zamówień, koszyk). To robi się przez sprawdzenie na POCZĄTKU takiej strony, czy sesja zawiera dane zalogowanego użytkownika.
Wzorzec, który powtórzysz na każdej "chronionej" stronie:
session_start();
if (!isset($_SESSION["user_id"])) {
header("Location: logowanie.php");
exit();
}
// dalszy kod strony - wykona się TYLKO dla zalogowanych
header("Location: ...") przekierowuje przeglądarkę na inną stronę — MUSI być wywołane, zanim jakikolwiek HTML/echo zostanie wysłany (dokładnie tak samo jak session_start()). exit() po przekierowaniu jest konieczny — zatrzymuje wykonywanie reszty skryptu, żeby przypadkiem nie wykonał się kod "tylko dla zalogowanych", zanim przekierowanie zdąży zadziałać.
Przykład z życia
Spróbuj wejść na stronę swojego konta w dowolnym serwisie internetowym, będąc wcześniej wylogowanym — zamiast panelu zobaczysz przekierowanie na stronę logowania. To dokładnie ten mechanizm, którego się teraz nauczysz.
Kod (PHP)
<?php
// plik: panel.php - strona dostępna TYLKO dla zalogowanych
session_start();
if (!isset($_SESSION["user_id"])) {
header("Location: logowanie.php");
exit();
}
// od tego miejsca mamy pewność, że użytkownik jest zalogowany
echo "Witaj w swoim panelu, " . htmlspecialchars($_SESSION["email"]) . "!";
echo '<br><a href="wyloguj.php">Wyloguj się</a>';
Komentarz i wyjaśnienie kodu
isset($_SESSION["user_id"]) sprawdza, czy w sesji w ogóle ZAPISANO tę wartość — dzieje się to tylko po udanym logowaniu z Lekcji 15. Jeśli nie, header("Location: logowanie.php") każe przeglądarce natychmiast przejść na stronę logowania, a exit() zatrzymuje dalsze wykonywanie panel.php — bez exit() reszta kodu (widoczna tylko dla zalogowanych) i tak by się wykonała, tylko "w tle", zanim przekierowanie zdążyłoby zadziałać w przeglądarce.
Ćwiczenie samodzielne
Dodaj taką samą ochronę do drugiej, wymyślonej przez siebie strony (np. koszyk.php) i sprawdź działanie, będąc raz zalogowanym, raz wylogowanym.
Zadania do pracy własnej
Dodaj mechanizm ochrony z tej lekcji do panelu z Lekcji 15 (zadanie trudne) i sprawdź, że próba wejścia bez zalogowania przekierowuje na formularz logowania.
Napisz wspólny plik ochrona.php zawierający tylko logikę sprawdzania sesji (bez reszty strony), który będziesz mógł dołączać przez require "ochrona.php"; na początku każdej chronionej strony — to unika powtarzania tego samego kodu wszędzie.
Zbuduj system dwóch poziomów dostępu: zwykły zalogowany użytkownik ($_SESSION["user_id"]) i administrator (dodatkowo $_SESSION["czy_admin"] = true, ustawiane tylko dla konkretnego konta). Strona panelu ma być dostępna dla każdego zalogowanego, a strona zarządzania filmami (dodawanie/usuwanie z Lekcji 10/12) — tylko dla administratora, z odpowiednim komunikatem "Brak uprawnień" dla zwykłych użytkowników.
Typowe błędy
Częsty błąd to sprawdzanie ochrony PO wypisaniu jakiegoś HTML-a — header() wywołane po jakimkolwiek echo zgłosi błąd "headers already sent". Drugi błąd: zapomnienie exit() po header() — przekierowanie "wygląda" na działające, ale reszta kodu strony i tak się wykonuje po stronie serwera. Trzeci: sprawdzanie ochrony osobno na każdej stronie z powtórzonym, nieco innym kodem — lepiej trzymać tę logikę w jednym wspólnym pliku (jak w zadaniu średnim).
Nawiązanie do egzaminu zawodowego
To praktyczne zastosowanie sesji (INF.03.5.4.7) w kontekście bezpieczeństwa aplikacji — element, który odróżnia "stronę z formularzem logowania" od faktycznie działającego systemu kont z prawdziwą kontrolą dostępu.