INF.03 · Aplikacje internetowe PHP
Ochrona stron przed niezalogowanymi użytkownikami
Zalogowany nie znaczy uprawniony do wszystkiego.
- PHP8.3
- mysqli · MariaDB
- Praktyka i diagnoza
Po tej lekcji: Ochronisz stronę i operację na rekordzie na serwerze, odróżniając uwierzytelnienie od autoryzacji.
Zrozum mechanizm
Uwierzytelnienie odpowiada kim jesteś, autoryzacja czy możesz wykonać tę konkretną czynność. Sprawdź sesję przed pobraniem prywatnych danych i przed HTML. Po header(Location) użyj exit — przekierowanie samo nie przerywa PHP. W pakiecie przekieruj() robi obie rzeczy.
WymagajLogowania broni panelu. Warunek wlasciciel_id z sesji w edytuj/usun broni rekordu. Nie przyjmuj ID właściciela lub roli z POST. Bezpośredni adres, zmienione ukryte pole i brak przycisku w interfejsie nie mogą omijać kontroli. Do testu potrzebne są dwa różne konta i osobne sesje.
Jak uruchamiać krótkie przykłady?
Każdy krótki przykład oznaczony własnym plikiem uruchamiaj osobno, nie doklejaj wszystkich definicji do jednego pliku. W edytorze zapisz go jako .php, a w terminalu tego folderu wpisz np. php for.php. Wtedy pokazane końce wierszy PHP_EOL są widoczne. W odpowiedzi HTML znak końca wiersza sam nie robi nowej linii na ekranie: użyj <br> albo znacznika <pre>. Wyświetl źródło pozwala zobaczyć tekst odpowiedzi.
Przykłady opisane jako fragment projektu wymagają paczki KINO / LAB i wcześniejszej konfiguracji. Nie uruchamiaj ich jako samodzielnych endpointów. Pełny plik niżej pokazuje kontekst. Funkcje h(), pole() i wymagajPost() są nasze; ich definicje wczytuje bootstrap.php.
Warunek dostępu musi być przed HTML
Sprawdzasz, czy sesja ma klucz user_id, zanim odczytasz i wypiszesz dane prywatne. isset zwraca false dla brakującego klucza lub null.
Podstawowa forma: if (!isset($_SESSION["user_id"])) { przekierowanie; exit; }
<?php
// Po bootstrap.php, który uruchomił sesję:
if (!isset($_SESSION['user_id'])) {
header('Location: /logowanie.php', true, 303);
exit;
}
echo 'Panel użytkownika';
-
!odwraca wynik isset: blok wykonuje się, gdy użytkownika NIE ma w sesji. - header wysyła nagłówek Location z adresem docelowym. 303 oznacza przekierowanie do odczytu strony docelowej.
- exit przerywa PHP; bez niego kod niżej mógłby nadal pobrać albo wypisać prywatne dane.
- wymagajLogowania() z projektu opakowuje tę kontrolę i zwraca int ID konta. Nadal osobno trzeba sprawdzić uprawnienie do konkretnego rekordu.
Jak czytać pozostałe zapisy w pełnym przykładzie
| Zapis | Znaczenie | Przykład użycia |
|---|---|---|
h($tekst) | Nasza funkcja kodująca tekst/atrybut HTML przez htmlspecialchars; nie wykonuje walidacji zakresu ani zabezpieczenia SQL. | h($film["tytul"]) |
wymagajLogowania() | Nasza funkcja: oddaje int ID konta z sesji lub przekierowuje do logowania. | $id = wymagajLogowania(); |
tokenFormularza() | Nasza funkcja zwraca HTML ukrytego pola csrf z wartością sesji zakodowaną przez h. | <?= tokenFormularza() ?> |
naglowek($tytul), stopka() | Nasze funkcje wypisujące wspólny HTML strony. void oznacza brak zwracanego wyniku do użycia w wyrażeniu. | naglowek("Katalog"); |
dirname(__DIR__) | dirname daje katalog nadrzędny; __DIR__ to katalog bieżącego pliku. W public prowadzi to do katalogu projektu, a dopisana ścieżka wskazuje src. | dirname(__DIR__)."/src/bootstrap.php" |
$_SESSION i $_POST | Specjalne tablice PHP: pierwsza to stan sesji, druga dane formularza POST. Zewnętrzne wartości trzeba sprawdzić, nie ufać samym nazwom kluczy. | $_SESSION["user_id"] |
-> oraz :: | -> wybiera właściwość lub metodę obiektu; :: odnosi się do elementu statycznego klasy. To nie jest zapis dostępu do tablicy. | $zapytanie->execute(); |
Sprawdź w działaniu
Zalogowany nie znaczy uprawniony do wszystkiego — sprawdź w modelu
Model w przeglądarce wyjaśnia mechanizm na fikcyjnych danych. Nie wykonuje PHP ani zapytań SQL i nie tworzy kont. Prawdziwe skrypty uruchomisz lokalnie z paczki.
Przewidź rezultat, wykonaj próbę i wyjaśnij, która decyzja po stronie serwera decyduje o wyniku.
Uruchom krok po kroku
Otwórz panel.php bez cookie. Następnie zaloguj kontoA, dodaj film i zapisz jego ID. W osobnym profilu zalogujB i spróbuj edytuj.php?id=ID_A. Oczekujesz 404, mimo żeB jest zalogowane. Nie zapisuj w raporcie wartości cookie ani danych prawdziwych osób.
Plik wzorcowy: public/panel.php
<?php
require_once dirname(__DIR__).'/src/db.php';
$idUzytkownika = wymagajLogowania(); // Sprawdzenie przed wysłaniem panelu.
$zapytanie = $polaczenie->prepare('SELECT id, tytul FROM Filmy WHERE wlasciciel_id=? ORDER BY id');
$zapytanie->bind_param('i', $idUzytkownika);
$zapytanie->execute();
$filmy = $zapytanie->get_result()->fetch_all(MYSQLI_ASSOC);
naglowek('Twój panel');
echo '<p>Witaj, '.h($_SESSION['email']).'.</p>';
?>
<p><a href="/dodaj.php">Dodaj własny film</a></p>
<?php foreach ($filmy as $film) { ?>
<article><h2><?= h($film['tytul']) ?></h2>
<a href="/edytuj.php?id=<?= (int) $film['id'] ?>">Edytuj</a>
<form method="post" action="/usun.php">
<?= tokenFormularza() ?><input type="hidden" name="id" value="<?= (int) $film['id'] ?>">
<button>Usuń ten film</button>
</form>
</article>
<?php } ?>
<form method="post" action="/wyloguj.php"><?= tokenFormularza() ?><button>Wyloguj</button></form>
<?php stopka();
Pobierz i odtwórz projekt
W „Źródłach i materiałach” na końcu pobierz KINO / LAB.zip. Rozpakuj całość; instrukcja START.txt opisuje konfigurację. Pierwsze 6 przykładów w public/podstawy działa bez bazy. Dalsze wymagają lokalnej MariaDB 11.4, importu schema.sql i lokalnego konta bazy z minimalnymi prawami. Gotowa paczka pokazuje całość, ale w tej lekcji wykonaj opisane kroki i własne zadanie.
Ćwiczenie z pomocą · samodzielna praca
Twoja próba — podpowiedzi otwieraj po kolei
Opracuj macierz dostępu: gość, właściciel i inne zalogowane konto dla panelu oraz edycji filmu.
Gość nie dostaje panelu; właściciel edytuje; inne konto otrzymuje 404 bez zmiany rekordu.
? Potrzebujesz pomocy? Rozwiązuj krok po kroku.
Krok 1 — pokaż podpowiedź
Odszukaj wskazany plik i zapisz przewidywany rezultat przed zmianą.
Krok 2 — pokaż podpowiedź
Zmień jedną rzecz. Sprawdź metodę żądania, dane i odpowiedź lub wynik programu.
Krok 3 — pokaż podpowiedź
Wykonaj próbę graniczną lub błędną. Porównaj także stan bazy lub sesji, nie tylko komunikat.
Otwórz tylko tyle podpowiedzi, ile potrzebujesz. Po każdym kroku wróć do zadania i sprawdź wynik.
Podsumowanie
Co warto zapamiętać
- Ochronisz stronę i operację na rekordzie na serwerze, odróżniając uwierzytelnienie od autoryzacji.
- Potrafisz wskazać w kodzie przyczynę wyniku i zaplanować próbę błędnych danych.
- Nie oddajesz haseł, pliku config.local.php ani wartości cookie.
Dalej na swoim koncie
Rozgrzewki, quiz i zadania są w biurku ucznia.
Teoria jest otwarta dla wszystkich. Żeby rozwiązywać zadania, zapisywać szkice i widzieć swój postęp, zaloguj się.
Zaloguj się →