W której tablicy superglobalnej w środowisku PHP powinno się przechowywać dane związane z logowaniem użytkownika w sposób zapewniający ich bezpieczeństwo?
A. $_FILES
B. $_SESSION
C. $_SERVER
D. $_COOKIE
Pytanie z egzaminu CKE, czerwiec 2022 (arkusz EE.09-SG-22.06).
Dane związane z zalogowaniem użytkownika najlepiej przechowywać w $_SESSION, bo sesja PHP jest mechanizmem przeznaczonym właśnie do utrzymywania stanu użytkownika między kolejnymi żądaniami HTTP. HTTP samo z siebie jest bezstanowe, więc serwer nie pamięta automatycznie, kto przed chwilą się zalogował. Po wywołaniu session_start() PHP tworzy identyfikator sesji, a właściwe dane sesyjne są trzymane po stronie serwera, np. informacja user_id, login, rola użytkownika czy czas ostatniej aktywności. Do przeglądarki trafia zwykle tylko identyfikator sesji w ciasteczku, a nie cała zawartość danych logowania. To jest ważne praktycznie, bo użytkownik nie powinien móc samodzielnie zmienić sobie roli z user na admin przez edycję danych w przeglądarce. Z mojego doświadczenia to jedna z pierwszych rzeczy, które warto dobrze zrozumieć w PHP. Dobre praktyki mówią też, żeby po zalogowaniu wykonać session_regenerate_id(true), ustawić ciasteczko sesji z flagami HttpOnly, Secure oraz SameSite, a w sesji nie trzymać hasła użytkownika, nawet zaszyfrowanego. Hasło powinno być w bazie jako hash utworzony np. przez password_hash(), a sesja ma przechowywać tylko bezpieczne minimum informacji potrzebnych aplikacji.
W tym pytaniu łatwo pomylić samo zapamiętanie danych w przeglądarce z bezpiecznym utrzymaniem stanu zalogowania. $_COOKIE bywa kuszące, bo ciasteczka rzeczywiście służą do przechowywania informacji między wizytami użytkownika, ale ich zawartość znajduje się po stronie klienta. Użytkownik może je podejrzeć, usunąć, a czasem także zmodyfikować. Da się oczywiście stosować podpisy, szyfrowanie i flagi HttpOnly, Secure oraz SameSite, ale nadal nie jest dobrą praktyką wkładanie tam roli użytkownika, hasła albo innych wrażliwych danych logowania. W ciasteczku powinien być najwyżej identyfikator sesji, a nie komplet informacji o autoryzacji. $_FILES ma zupełnie inne zastosowanie, bo obsługuje pliki wysłane formularzem, na przykład nazwę pliku, typ MIME, rozmiar i tymczasową ścieżkę na serwerze. Trzymanie tam danych logowania nie ma sensu technicznego, bo ta tablica istnieje w kontekście przesyłania plików metodą POST z enctype multipart/form-data. $_SERVER również nie jest miejscem na dane użytkownika po logowaniu. Zawiera informacje o serwerze, żądaniu HTTP, nagłówkach, adresie IP czy ścieżce skryptu. Część tych danych może pochodzić od klienta i nie wolno im ufać bez walidacji. Typowy błąd myślowy polega na tym, że ktoś widzi globalną tablicę i zakłada, że każda nadaje się do przechowywania dowolnych danych. W PHP każda z tych tablic ma konkretną rolę, a do mechanizmu logowania i autoryzacji służy przede wszystkim $_SESSION, najlepiej używana razem z poprawną konfiguracją ciasteczek sesyjnych i kontrolą uprawnień po stronie serwera.