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; }

guard.phpphp
<?php
// Po bootstrap.php, który uruchomił sesję:
if (!isset($_SESSION['user_id'])) {
    header('Location: /logowanie.php', true, 303);
    exit;
}
echo 'Panel użytkownika';
  1. ! odwraca wynik isset: blok wykonuje się, gdy użytkownika NIE ma w sesji.
  2. header wysyła nagłówek Location z adresem docelowym. 303 oznacza przekierowanie do odczytu strony docelowej.
  3. exit przerywa PHP; bez niego kod niżej mógłby nadal pobrać albo wypisać prywatne dane.
  4. 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

ZapisZnaczeniePrzykł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 $_POSTSpecjalne 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.

Ta interakcja wymaga włączonego JavaScriptu.

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

public/panel.phpphp
<?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.

Oczekiwany rezultat
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ć

  1. Ochronisz stronę i operację na rekordzie na serwerze, odróżniając uwierzytelnienie od autoryzacji.
  2. Potrafisz wskazać w kodzie przyczynę wyniku i zaplanować próbę błędnych danych.
  3. 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ę →
Źródła i dalsza nauka