Lekcja 15. Logowanie i wylogowanie użytkownika
Trudny / egzaminacyjnyPo 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
Napisz formularz logowania z polami e-mail i hasło oraz skrypt sprawdzający dane względem tabeli Uzytkownicy z Lekcji 14.
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.
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.