Sesje to bardzo przydatny mechanizm i chyba nikogo nie trzeba do tego przekonywać. Opisywany dzisiaj problem tak naprawdę nie dotyczy bezpośrednio sesji. Mimo to, to właśnie podczas pracy z sesjami ludzie najczęściej wykrywają problem.
Logując użytkownika na naszej stronie jesteśmy przekonani, że na każdej podstronie trzeba wystartować sesję i już mamy załatwiony problem przenoszenia informacji o użytkownikach podczas poruszania się po naszej witrynie. Niestety, nie zawsze.
Identyfikator sesji można przekazywać między stronami na dwa sposoby: poprzez plik cookie lub za pomocą adresu URL. Pierwszy jest wygodny ale zapisywanie ciasteczek może być wyłączone przez użytkownika. Drugi jest kłopotliwy. PHP samo dba o doklejanie identyfikatora do wszystkich adresów ale ten mechanizm nie jest w stanie wykryć wszystkich dziwnych sytuacji i czasami sami musimy mu dopomóc. Ponadto metoda ta zwiększa zagrożenie przejęcia aktywnej sesji przez inną osobę.
Na szczęście niewiele osób wyłącza ciasteczka i raczej wszyscy programiści skłaniają się do pierwszej metody.
Problem pojawia się gdy nasza strona ma adresy w subdomenach np. abc.tarnaski.eu. Dla naszej przeglądarki to jest zupełnie inny adres od samego tarnaski.eu (nawet www.tarnaski.eu i tarnaski.eu to tak naprawdę dwa różne adresy) i nie przekazuje dalej ciasteczka z identyfikatorem sesji. Można jednak temu zaradzić.
Każdemu ciasteczku możemy ustawić parametr, który podpowiada przeglądarce dla jakiej domeny dane ciasteczko jest widoczne. Oczywiście przeglądarki zabezpieczają się przed ustawieniem ciasteczka dla zupełnie obcej domeny. Nie możemy zmieniać ciastek na komputerze użytkownika, które zostały ustawione przez inne strony www. To byłaby straszna luka bezpieczeństwa. Możemy natomiast rozporządzać własną domeną.
Domyślnie każde ciastko jest dostępne tylko i wyłącznie dla adresu domeny z której to ciastko zostało wywołane. Jeżeli więc ustawimy ciastko z adresu tarnaski.eu to wchodząc na adres abc.tarnaski.eu przeglądarka nie przekaże naszemu serwerowi informacji o ciasteczku. W przypadku sesji, identyfikator nie będzie znany i PHP uzna, że ten użytkownik dopiero wszedł na naszą stronę i wygeneruje nowy SID.
Możemy to jednak zmienić. Dla sesji istnieje specjalna funkcja, która pozwala nam ustawić parametry naszego ciasteczka sesyjnego. Nazywa się session_set_cookie_params(). Poniżej prezentuję przykład użycia:
Dokładniejsze informacje o tej funkcji znajdziesz w manualu. Nas w tej chwili interesuje trzeci parametr. Oto rozwiązanie zagadki. Należy ustawić tu naszą domenę z kropką na początku. To jasna informacja dla przeglądarki, że ciastko ma być dostępne dla domeny głównej i dla wszystkich subdomen. Od teraz Twoi użytkownicy nie będą wylogowywani gdy będą poruszali się między subdomenami Twojej witryny.
Tak jak napisałem na początku, problem dotyczy nie tyle sesji co mechanizmu ciasteczek. Pamiętaj o tym bo być może w przyszłości będziesz chciał przekazać między subdomenami jakieś własne ciastko. Mechanizm zachowania jest identyczny tylko domenę ustawiasz bezpośrednio w funkcji setcookie().
Ciekawostka
Istnieją inne sposoby ustawienia domeny dla ciastka sesyjnego. Jeżeli masz dostęp do uruchamiania funkcji ini_set() to możesz użyć takiego kodu:
PHP:
-
ni_set('session.cookie_domain', '.tarnaski.eu');
Natomiast z poziomu pliku .htaccess (oczywiście potrzebne są odpowiednie uprawnienia, nie na każdym hostingu to zadziała) możesz zrobić to:
CODE:
-
php_value session.cookie_domain .tarnaski.eu