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.

PRZEGLĄDARKAżądanieprodukt/42SERWERzapytanie SQLWHERE id=42BAZA DANYCHrekordproduktuSERWERszablon +dane w HTMLPRZEGLĄDARKAgotowastronadynamiczna strona: treść budowana z bazy na żądanie1 szablon × rekordy bazy = tysiące stron (seryjność w sieci)UWAGA: wejście użytkownika = dane, nie kod (parametryzuj SQL, oczyszczaj HTML)
Przepływ dynamicznej strony: przeglądarka wysyła żądanie produkt/42 do serwera aplikacji, ten odpytuje bazę zapytaniem SQL, otrzymuje rekord, wstawia dane w szablon HTML i odsyła gotową stronę do przeglądarki. · rys. własny

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/42 w 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

  1. 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).

  1. 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ą.

  1. 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 &lt; 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

Ucz się tej jednostki z asystentem