Gdzie przechowywane są sesje PHP. Sesje PHP pod skalpelem
W Internecie można znaleźć tysiące samouczków na temat tego, co sesje są za to, czego potrzebują i jak z nimi pracować. Ale niestety, po ich przeczytaniu wiele pytań pozostaje. Moim zdaniem najprostszy sposób na zrozumienie tego we wszystkim, aby zobaczyć, jak działa sesje od wewnątrz. Te. Sprawdź dzienniki udostępniania przeglądarki i serwera WWW, a także zobacz, jakie dane są zapisywane po stronie klienta i po stronie serwera.
Potem wiele chwil staje się znacznie wyraźniejszy, a sam mechanizm jest bardziej przejrzysty.
Sesje będą badane w następnym skrypcie standardowym:
Działa w następujący sposób:
Blok 1. Funkcja session_start () tworzy nową sesję lub ładuje stare, przy użyciu unikalnego identyfikatora sesji fSESID.
Blok 2. Jeśli udało ci się przywrócić sesję, wartość $ _Session ["Widoki"] wzrasta przez jednego. Jeśli nie, jest inicjowany przez jednego.
W teorii, jeśli w przeglądarce jest włączona obsługa gotowania, mechanizm musi pracować, a za każdym razem, gdy strona jest aktualizowana, wartość licznika wzrośnie przez jeden.
Pierwszy skrypt ładowania
Żądanie nagłówków
Get / HTTP / 1.1 Host: FiRingrange.Local User-Agent: Mozilla / 5.0 (Windows NT 5.1; RV: 6.0.2) Gecko / 20100101 Firefox / 6.0.2 Akceptacja: Tekst / HTML, Aplikacja / XHTML + XML, Aplikacja / XML; q \u003d 0,9, * / *; q \u003d 0,8 Akceptować-Język: RU-PL, RU; q \u003d 0,8, EN-US; Q \u003d 0,5, PL; Q \u003d 0,3 Akceptowanie kodowania: GZIP, Deflacja Akceptuj : Windows-1251, UTF-8; q \u003d 0,7, *; q \u003d 0.7 Połączenie: Keep-Alive Cache-Control: Max-Age \u003d 0Odpowiedź nagłówki
HTTP / 1.1 200 OK Data: Czw, 29 wrz 2011 20:36:15 GMT Serwer: Apache / 2.2.13 (Win32) PHP / 5.2.10 X-Powered-by: PHP / 5.2.10 Set-Cookie: Phpssid \u003d K33EN6CCGIA7125MITJ5TE4U6; ścieżka \u003d / Wygasa: Czw, 19 listopada 1981 08:52:00 GMT Cache-Control: No-Store, No-Cache, Must-Revalidate, Post-Check \u003d 0, Pre-Check \u003d 0 Pragma: No-Cache Content Długość: 58 Utrzymuj: limit czasu \u003d 5, max \u003d 100 Połączenie: Keep-Alive Content-Type: Tekst / HTMLKomentarz
W pierwszym wniosku przeglądarka nie zidentyfikowała się w żaden sposób, więc mechanizm sesje PHP. Wygenerowałem nowy unikalny identyfikator sesji i nakazał przeglądarkę, aby utworzyć wiązkę, w której ten identyfikator zostanie zapisany.
Side Server.
W wyniku skryptu po stronie serwera powstaje SESS_K33EN6CCGIA7125MITJ5TE4U6 z poniższych treści:
Strona klienta
Po stronie klienta powstaje Phpsessid Cook, w którym przechowywana jest wartość unikalnego identyfikatora sesji.
Uwaga. Dla ustawienia PHP. Domyślnie żywotność gotowania phpssid - aż przeglądarka zostanie zamknięta. Te. Gdy tylko przeglądarka zostanie zamknięta, gotowanie zostanie usunięte, a sesja zostanie odpowiednio utracona. Życie Phpsesid Cookie można zmienić, zmieniając wartość session.cookie_lifetime.
Wynik pracy skryptu
Skrypt drugiego ładowania
Żądanie nagłówków
Get / HTTP / 1.1 Host: Firingrange.local User-Agent: Mozilla / 5.0 (Windows NT 5.1; RV: 6.0.2) Gecko / 20100101 Firefox / 6.0.2 Akceptuj: Tekst / HTML, Zastosowanie / XHTML + XML, Zastosowanie / XML; q \u003d 0,9, * / *; q \u003d 0,8 Akceptuj język: RU-EN, RU; Q \u003d 0,8, EN-US; Q \u003d 0,5, PL; q \u003d 0,3 Akceptuj kodowanie: Gzip, Deflatuj Akceptuj-Charset: Windows-1251, UTF-8; Q \u003d 0,7, *; q \u003d 0,7 Połączenie: Phps-Alive Cookie: Phpsesid \u003d K33EN6CCCGIA7125MITJ5TE4U6 Cache-Control: Max-Age \u003d 0Odpowiedź nagłówki
HTTP / 1.1 200 OK Data: Czw, 29 wrz 2011 20:49:41 Serwer GMT: Apache / 2.2.13 (Win32) PHP / 5.2.10 X-Powered-by: PHP / 5.2.10 Wygasa: Czw, 19 listopada 1981 08:52:00 GMT Cache-Control: No-Store, No-Cache, Must-Revalidate, Post-Check \u003d 0, Pre-Check \u003d 0 Pragma: No-Cache Content Długość: 58 Keep-Alve: Timeout \u003d 5, Max \u003d 100 Połączenie: Test-Alive Content-Type: Tekst / HTMLKomentarz
Przeglądarka wysyła serwer internetowy Phpsesid Cook za pomocą PHP inicjuje tablicę $ _Session z wartościami z pliku SESS_K33EN6CCGIA7125MITJ5TE4U6. Odpowiednio, w bloku 2 działa, jeśli (prosta) oddział.
Side Server.
W wyniku operacji skryptu, zawartość pliku SESS_K33EN6CCCIA7125MITJ5TE4U6 jest zmiana:
Strona klienta
Klient nie zmienia się na kliencie.
Wynik pracy skryptu
Co dalej?
Późniejsze pliki do pobrania strony przed zamknięciem przeglądarki będzie działać przez analogię z tym, jak działało drugie ładowanie skryptu.
Dlatego Life Cook's Life był ograniczony do bieżącej sesji przeglądarki, a następnie po zamknięciu unikalny identyfikator sesji zostanie utracony i podczas ponownego uruchomienia procesu pójdzie na nowy.
Jednak można powrócić do zapisanej sesji, jeśli wyraźnie określiłeś PHSESSID jako parametr skryptu:
Wróć do sesji jest dość warunkowa, ponieważ W wyniku operacji skryptu w tym przypadku Cook nie jest tworzony. Nagłówki odpowiedzi serwera:
HTTP / 1.1 200 OK Data: Czw, 29 wrz 2011 21:01:52 Serwer GMT: Apache / 2.2.13 (Win32) PHP / 5.2.10 Powered-przez: PHP / 5.2.10 Wygasa: Czw, 19 listopada 1981 08:52:00 GMT Cache-Control: No-Store, No-Cache, Must-Revalidate, Post-Check \u003d 0, Pre-Check \u003d 0 Pragma: No-Cache Content Długość: 58 Keep-Alve: Timeout \u003d 5, Max \u003d 100 Połączenie: Test-Alive Content-Type: Tekst / HTML
Te. Aby utrzymać pracę, z tej sesji do wszystkich powiązań należy przypisać? Phpsesid \u003d K33EN6CCGIA7125MITJ5TE4U6.
Uwaga. Możesz określić PHP, aby unikalny identyfikator sesji jest przesyłany tylko przez kucharza. Aby to zrobić, zainstalować session.use_only_cookies w wartości 1. W tym przypadku sztuczka, wykazana powyżej, nie przejdzie.
Jeśli pliki cookie są wyłączone w przeglądarce, możesz przesłać identyfikator sesji przez parametry, jak zrobiliśmy powyżej. Ponadto w PHP jest mechanizm, który zwiększy żądany parametr do łącza i dodać ukryte pola do formularza. Zasada działania jest dokładnie taka sama jak w przypadku plików cookie, więc nie będziemy zdemontować tej sprawy oddzielnie.
Mały kwestionariusz (FAQ)
Gdzie są dane sesji są fizycznie przechowywane?
Dane sesji są przechowywane na serwerze. Domyślnie są one rejestrowane w plikach, ale można określić własny mechanizm przechowywania danych sesji (na przykład za pomocą bazy danych). Jeśli chcesz, zobacz funkcję session_set_save_handler.
Kto generuje unikalny identyfikator sesji?
Unikalny identyfikator sesji (Phpsesid) generuje serwer.
Czy można napisać własny mechanizm sesji?
Tak, jest całkiem możliwe. Jak widać, PHP nie używa niczego supernatural - identyfikator jest zapisywany między żądaniami z kucharzem, dane sesji są przechowywane w plikach na serwerze.
Na przykład, własny mechanizm pracy z sesjami jest w popularnym ramowym Codeignal.
Jak bezpieczny jest mechanizm sesji?
Sesja jest identyfikowana tylko przy pomocy unikalnego identyfikatora sesji, więc w ogólnym przypadku atakujący wystarczy, aby go ukraść, aby pomylić serwer. Weź skrypt testowy, który użyliśmy powyżej. Jeśli odwołanie jest z innego adresu IP (w odniesieniu do utworzonej sesji), ale fSESID będzie przesyłany tak samo, wówczas sesja zostanie pomyślnie przywrócona, a licznik wzrośnie z poprzedniej zapisanej wartości.
Zapewnienie dodatkowej ochrony będzie dla Ciebie. Na przykład:
- Możesz zapisać w danych sesji IP i klienta użytkownika (będą przechowywane po stronie serwera), a następnie przy każdym uchwycie konieczne jest weryfikację, czy wartości bieżące są zbiegły się z zapisanym. W tym przypadku musisz szukać kompromisu między bezpieczeństwem a wygodą użytkownika.
Na przykład, jeśli użytkownik ma dynamiczny IP i korzystasz z sesji, aby utrzymać autoryzację, ale jednocześnie sprawdzić nawigację OD, a następnie z każdą zmianą adresu użytkownik będzie musiał ponownie wprowadzić nazwę użytkownika i hasło.
Podobnie ciąg agenta użytkownika może się zmieniać podczas aktualizacji wersji przeglądarki lub podczas instalacji niektórych wtyczek.
- Jednym z zalecanych mechanizmów ochrony sesji jest ponowne wygenerowanie identyfikatora za każdym razem, gdy odwołania skryptów (patrz funkcja session_regenerate_id). Wyświetl skrypt i algorytm pracy w sekcji może być poniżej.
Uwaga.Jeśli wierzysz na dyskusję na oficjalnej stronie internetowej, a następnie podczas ponownego wygenerowania identyfikatora, problemy mogą pojawić się z równoległym dostępem do danych.
Sesje robocze z identyfikatorem ponownego wygenerowania w kontekście
Scenariusz
// blok 1.
session_start ();
gdyby.(iset.($ _Session ["zainicjowany"]))
session_regenerate_id ();
jESZCZE.
$ _Session ["iniciated"] \u003d prawdziwe.;
// blok 2.
gdyby.(iset.($ _Session ["Widoki"]))
$ _SESSION ["Widoki"] ++;
jESZCZE.
$ _SESSION ["Widoki"] \u003d 1;
// Blok 3.
echo."
<
body>
Liczba poglądów: ". $ _Session [" Widoki "]."