Dataczwartek, 13 sierpnia 2026 Czas18:20:50
← Aplikacje internetowe (PHP)

Lekcja 15. Logowanie i wylogowanie użytkownika

Trudny / egzaminacyjny

Po co się tego uczymy?

Rejestracja bez logowania to konto, z którego nikt nie może skorzystać. To druga połowa systemu użytkowników — i moment, w którym po raz pierwszy używasz sesji (Lekcja 13) do czegoś naprawdę przydatnego: zapamiętania, że dana osoba jest zalogowana.

Teoria

Logowanie to odwrotność rejestracji: użytkownik podaje e-mail i hasło, a PHP sprawdza, czy taki użytkownik istnieje w bazie i czy podane hasło zgadza się z zapisanym hashem.

Kroki logowania:
1. Pobierz z bazy wiersz użytkownika o podanym e-mailu (SELECT).
2. Jeśli taki użytkownik istnieje, porównaj podane hasło z hashem z bazy funkcją password_verify($wpisaneHaslo, $hashZBazy).
3. Jeśli hasło się zgadza — zapisz w sesji informację, że użytkownik jest zalogowany, np. $_SESSION["user_id"] = $wiersz["id_uzytkownika"];
4. Jeśli e-mail nie istnieje ALBO hasło się nie zgadza — pokaż JEDEN, ogólny komunikat błędu ("Nieprawidłowy e-mail lub hasło"), nie zdradzając, które z pól było błędne — to zapobiega "zgadywaniu", czy dany e-mail jest zarejestrowany.

Wylogowanie jest proste: session_start(); session_unset(); session_destroy(); — czyści dane sesji i kończy ją całkowicie.

Przykład z życia

Logowanie na dowolnej stronie internetowej — jeśli wpiszesz zły e-mail LUB złe hasło, strona (dobrze zaprojektowana) zawsze pokaże ten sam, ogólny komunikat "nieprawidłowe dane logowania", zamiast zdradzać, czy to konkretny e-mail nie istnieje, czy tylko hasło jest błędne.

Kod (PHP)

<?php
session_start();
$polaczenie = mysqli_connect("localhost", "root", "", "serwis_filmowy");

if (isset($_POST["email"]) && isset($_POST["haslo"])) {
    $email = mysqli_real_escape_string($polaczenie, $_POST["email"]);
    $haslo = $_POST["haslo"];

    $wynik = mysqli_query($polaczenie, "SELECT * FROM Uzytkownicy WHERE email = '$email'");

    if (mysqli_num_rows($wynik) === 1) {
        $uzytkownik = mysqli_fetch_assoc($wynik);

        if (password_verify($haslo, $uzytkownik["haslo"])) {
            $_SESSION["user_id"] = $uzytkownik["id_uzytkownika"];
            $_SESSION["email"] = $uzytkownik["email"];
            echo "Zalogowano pomyślnie! Witaj, " . htmlspecialchars($uzytkownik["email"]);
        } else {
            echo "Nieprawidłowy e-mail lub hasło.";
        }
    } else {
        echo "Nieprawidłowy e-mail lub hasło.";
    }
}

mysqli_close($polaczenie);

// plik: wyloguj.php
session_start();
session_unset();
session_destroy();
echo "Zostałeś wylogowany.";

Komentarz i wyjaśnienie kodu

mysqli_num_rows($wynik) === 1 sprawdza, czy znaleziono DOKŁADNIE jednego użytkownika o takim e-mailu (dzięki UNIQUE na kolumnie email z Lekcji o więzach integralności, nigdy nie powinno być więcej). password_verify() samodzielnie "wie", jak porównać zwykłe hasło z hashem — nie musisz (i nie powinieneś) samodzielnie haszować hasła przy logowaniu, żeby je porównać. Po udanym logowaniu zapisujemy w sesji $_SESSION["user_id"] — to właśnie ta wartość będzie sprawdzana w Lekcji 16, żeby stwierdzić, czy ktoś jest zalogowany na innych podstronach.

Ćwiczenie samodzielne

Dodaj do formularza logowania checkbox "zapamiętaj mnie" (na razie bez pełnej implementacji — po prostu odbierz jego wartość z $_POST i wypisz, czy była zaznaczona).

Zadania do pracy własnej

  1. Napisz formularz logowania z polami e-mail i hasło oraz skrypt sprawdzający dane względem tabeli Uzytkownicy z Lekcji 14.

  2. Rozbuduj logowanie tak, żeby po sukcesie zapisywało w sesji także imię użytkownika, a na stronie głównej wyświetlało "Zalogowano jako: [imię]" zamiast e-maila.

  3. Zbuduj kompletny cykl: formularz logowania → sprawdzenie danych → zapis do sesji przy sukcesie → strona "panel.php", która wyświetla dane zalogowanego użytkownika i ma link "Wyloguj" prowadzący do skryptu czyszczącego sesję.

Typowe błędy

Częsty błąd to osobne komunikaty "zły e-mail" i "złe hasło" — to ułatwia atakującemu sprawdzenie, które adresy e-mail są zarejestrowane w systemie (dlatego zawsze jeden, wspólny komunikat). Drugi błąd: porównywanie haseł przez zwykłe == zamiast password_verify() — hash nigdy nie będzie równy oryginalnemu hasłu, bo to zupełnie inny ciąg znaków. Trzeci: brak session_start() na stronie z formularzem logowania, przez co $_SESSION[...] ustawione po zalogowaniu "znika" na kolejnych stronach.

Nawiązanie do egzaminu zawodowego

To razem z Lekcją 14 kompletna realizacja typowego "systemu kont użytkowników", łącząca efekty INF.03.5.4.5 (baza danych) i 03.5.4.7 (sesje) — jeden z najbardziej charakterystycznych elementów prawdziwej aplikacji internetowej.