Strona z bazą danych
🎯 Po co Ci to?
Strona z 13.6 była statyczna — te same treści dla każdego, zmieniane tylko ręczną edycją HTML. Ale sklep pokazujący 10 000 produktów, portal z profilami użytkowników, ten system z lekcjami i ocenami — nie mają 10 000 ręcznie napisanych stron. Mają jedną stronę-szablon, która pobiera treść z bazy danych (dział 12!) i buduje ją na żądanie. To jest strona dynamiczna — i to ona stoi za niemal całym użytecznym internetem. Ta jednostka spina dwa działy części III (bazy + WWW) w jeden mechanizm, którego znajomość jest przepustką do tworzenia prawdziwych aplikacji internetowych. Rozszerzona podstawa wymaga elementów strony współpracujących z siecową bazą danych.
✅ Czego się nauczysz
Po tej jednostce potrafisz:
- odróżnić stronę statyczną od dynamicznej (generowanej z danych);
- opisać przepływ: żądanie → serwer → zapytanie do bazy → wygenerowany HTML → przeglądarka;
- wskazać, gdzie w tym przepływie leżą kwestie bezpieczeństwa (z 12.6).
🔁 Przypomnij sobie
Z 13.6: HTML+CSS, strona statyczna; z 12.6: architektura klient–serwer, baza w sieci, SQL injection; z 12.3: kwerenda jako żywe pytanie do bazy.
📘 Wyjaśnienie
Statyczna vs dynamiczna. Strona statyczna (13.6) to gotowy plik HTML — serwer odsyła go bez zmian, każdemu ten sam. Strona dynamiczna to szablon + program: serwer generuje HTML na żądanie, wstawiając dane z bazy. Katalog sklepu nie jest 10 000 plików — to jeden szablon „strona produktu", który dla adresu .../produkt/42 pobiera z bazy produkt o id=42 i buduje jego stronę. Jeden szablon, tysiące stron — rozpoznajesz? To korespondencja seryjna (13.4) w internecie: szablon × rekordy bazy = strony. Albo, patrząc inaczej, to arkuszowa „formuła zamiast wartości" (11.1) na skalę sieci — treść liczona z danych, nie zamrożona.
Przepływ dynamicznej strony. Prześledźmy, co się dzieje, gdy klikasz produkt w sklepie (architektura z 12.6 w akcji):
1. PRZEGLĄDARKA: żądanie adresu .../produkt/42
2. SERWER APLIKACJI: odbiera; buduje zapytanie (parametryzowane!):
SELECT * FROM produkty WHERE id = 42
3. BAZA DANYCH: wykonuje zapytanie (indeks → milisekundy, 12.4), zwraca rekord
4. SERWER: wstawia dane produktu w szablon HTML (nazwa, cena, opis w odpowiednie miejsca)
5. PRZEGLĄDARKA: dostaje gotowy HTML, wyświetla — użytkownik widzi stronę produktu
Cały cykl trwa ułamek sekundy i powtarza się przy każdym kliknięciu, dla każdego z tysięcy użytkowników naraz (współbieżność z 12.6). Strona, którą widzisz, powstała przed chwilą, specjalnie dla Twojego żądania, z aktualnych danych bazy — dlatego cena jest bieżąca, a stan magazynu prawdziwy. To jest istota nowoczesnego internetu: treść generowana z danych na żądanie.
Bezpieczeństwo w przepływie. Każdy element danych od użytkownika (adres, formularz wyszukiwania, dane logowania) wchodzi do tego przepływu — i każdy jest potencjalną bramą ataku (12.6). Trzy newralgiczne punkty: (1) budowa zapytania — musi być parametryzowana (SQL injection z 12.6! .../produkt/42 gdzie „42" to 42; DROP TABLE produkty — parametryzacja czyni to nieszkodliwym); (2) dane wyświetlane — treść od użytkowników (komentarze!) wstawiana w HTML bez oczyszczenia pozwala wstrzyknąć złośliwy skrypt (atak XSS — kuzyn SQL injection, tym razem w HTML); (3) uprawnienia — serwer musi sprawdzić, czy użytkownik może zobaczyć/zmienić dane (czy to jego zamówienie? — echo „gate'owania per zasób" z opisu tego systemu). Bezpieczna aplikacja dynamiczna to nie dodatek — to sposób budowania każdego z pięciu kroków przepływu, od pierwszej linijki (12.6!).
💭 Pomyśl: Dwie osoby otwierają tę samą stronę sklepu
.../produkt/42w tej samej sekundzie, ale jedna widzi „dostępny", druga „wyprzedany" (ktoś kupił ostatni między ich kliknięciami). Czy to błąd? Jak strona dynamiczna radzi sobie z tym, że dane zmieniają się w trakcie?
Sprawdź odpowiedź
To nie błąd — to poprawne działanie strony dynamicznej: każda generuje się z aktualnego stanu bazy, a ten zmienił się między dwoma żądaniami (ktoś kupił ostatni egzemplarz). Pierwsza osoba dostała HTML sprzed zakupu, druga — po. To jest właśnie zaleta dynamiki (dane na żywo, 12.3), z jej naturalną konsekwencją: strona to migawka stanu z chwili żądania. Prawdziwy problem pojawia się dopiero przy zakupie: jeśli pierwsza osoba (widząca „dostępny") kliknie „kup" po tym, jak druga już kupiła — to musi zadziałać kontrola współbieżności z 12.6 (transakcja + blokada), która pozwoli sfinalizować tylko jeden zakup, a drugiej pokaże „niestety, wyprzedano". Wyświetlenie może być nieaktualne (nic złego), ale operacja zmieniająca stan musi być chroniona transakcyjnie. Rozróżnienie „odczyt może być stary / zapis musi być spójny" to sedno projektowania systemów z danymi na żywo.
⚠️ Uwaga, pułapka
Kusi, by w prostym projekcie „na skróty" wkleić dane użytkownika wprost do zapytania SQL i do HTML — „przecież to działa". Działa — do pierwszego, kto wpisze '; DROP TABLE... w wyszukiwarkę albo <script>... w komentarz. Obie luki (SQL injection i XSS) wynikają z tego samego grzechu: traktowania danych od użytkownika jak zaufanego kodu. Reguła uniwersalna, którą wynosisz z całej książki (echo działu 1: dane od świata bywają wrogie): wejście użytkownika to zawsze dane, nigdy kod — parametryzuj zapytania (12.6), oczyszczaj treść wstawianą w HTML. To nie paranoja, to higiena — a wbudowana od początku jest darmowa (jak dostępność, jak testowanie).
🛠️ Teraz Ty
Bez kodu — projekt na papierze: zaprojektuj dynamiczną stronę „katalog książek szkolnej biblioteki" na bazie z 12.2. Naszkicuj: (1) jakie adresy (np. /ksiazki, /ksiazka/{id}, /szukaj?fraza=...); (2) dla każdego — jakie zapytanie SQL serwer wykona; (3) jak wygląda szablon HTML strony książki (które dane z bazy wstawia i gdzie); (4) wskaż dwa miejsca zagrożenia (SQL injection, XSS) i obronę każdego. To ćwiczenie spina całą część III w jeden system.
📐 Definicje tej lekcji
- Strona statyczna / dynamiczna — gotowy plik, ten sam dla każdego / generowana na żądanie z danych bazy (szablon + rekordy).
- Przepływ dynamiczny — żądanie → serwer → zapytanie SQL → dane → wstawienie w szablon → HTML do przeglądarki.
- XSS — atak przez wstrzyknięcie skryptu w treść wyświetlaną w HTML; obrona: oczyszczanie danych użytkownika przed wyświetleniem.
📌 Najważniejsze w pigułce
- Dynamiczna strona = szablon + baza; jeden szablon generuje tysiące stron z danych (seryjność 13.4 w sieci).
- Przepływ: żądanie → SQL → dane → HTML; treść liczona z aktualnego stanu bazy (formuła, nie wartość — 11.1).
- Każde wejście użytkownika to dane, nie kod: parametryzuj SQL (injection), oczyszczaj HTML (XSS) — od pierwszej linijki.
🎒 Zadania
- Wyjaśnij, czemu sklep z 10 000 produktów ma jedną dynamiczną stronę-szablon, a nie 10 000 statycznych plików HTML. Wymień trzy zalety.
Wskazówka i odpowiedź
(1) Utrzymanie: zmiana wyglądu strony produktu = edycja jednego szablonu, nie 10 000 plików (kaskada, jak style/CSS!). (2) Aktualność: cena i dostępność zawsze bieżące (z bazy), nie zamrożone w plikach; dodanie produktu = jeden rekord w bazie, strona pojawia się sama. (3) Rozmiar/wykonalność: nikt nie napisze ręcznie 10 000 stron, a przy zmianie ceny nie poprawi ich wszystkich. To dokładnie „jedno źródło prawdy" (dane w bazie) + „szablon zamiast kopii" — zasada domykająca całą część III (formuła nie wartość, styl nie ręczne formatowanie, szablon seryjny, dynamiczna strona: cztery wcielenia jednej idei).
- Adres
/szukaj?fraza=[to, co wpisał użytkownik]trafia do zapytania SQL wyszukującego książki. Pokaż, jak atakujący mógłby to wykorzystać (SQL injection) i jak parametryzacja go blokuje.
Wskazówka i odpowiedź
Atak: fraza = ' OR '1'='1 daje WHERE tytuł LIKE '%' OR '1'='1%' — warunek zawsze prawdziwy, zwraca całą bazę (a sprytniejsze wstrzyknięcie wyciągnie hasła albo skasuje tabele — 12.6). Mechanizm: wejście zmieniło strukturę zapytania, bo zostało wklejone jako kod SQL. Obrona: zapytanie parametryzowane — fraza trafia jako wartość parametru (baza szuka dosłownie tekstu ' OR '1'='1, którego żaden tytuł nie zawiera), nigdy jako fragment SQL. Ta sama zasada co w 12.6, tu w kontekście dynamicznej strony: parametr = dane, nie kod. Jedna reguła chroni każdą aplikację z bazą.
- Portal pozwala użytkownikom komentować. Ktoś w komentarzu wpisuje
<script>uk_radnij_ciasteczka()</script>. Co się stanie, jeśli portal wyświetli komentarz bez oczyszczenia (XSS), i jaka jest obrona?
Wskazówka i odpowiedź
Bez oczyszczenia: komentarz wstawiony w HTML strony wykona się jako skrypt w przeglądarce każdego, kto obejrzy stronę z tym komentarzem — może wykraść ich dane sesji/ciasteczka, podszyć się pod nich, przekierować. To XSS (cross-site scripting) — kuzyn SQL injection, tym razem wstrzyknięty kod działa w HTML/przeglądarce, nie w bazie. Obrona: oczyszczanie (escaping) danych użytkownika przed wstawieniem w HTML — zamień < na < itd., tak by <script> wyświetlił się jako tekst „<script>", a nie wykonał jako kod. Wspólny mianownik z SQL injection: wejście użytkownika (komentarz) potraktowane jak kod zamiast jak dane. Reguła „wejście to dane, nie kod" chroni na obu frontach — w SQL i w HTML. (Ta sama zasada, którą ten system stosuje: markery/wejście ucznia traktowane jako treść, nie instrukcje.)
🔍 Sprawdź, czy umiesz
- Odróżnić stronę statyczną od dynamicznej i wyjaśnić „szablon + baza".
- Prześledzić przepływ dynamicznej strony przez pięć kroków.
- Wskazać SQL injection i XSS w przepływie oraz wspólną obronę „wejście to dane, nie kod".
CZĘŚĆ IV — Maszyny, sieci, społeczeństwo