Kontrolowanie czasu sesji w PHP
Potrzebowałem ostatnio wydłużyć czas trwania sesji, znacznie ponad standardowe 24 minuty. Jak wiemy, mechanizm sesji umożliwia przechowywanie na serwerze danych dotyczących klientów(przeglądarek), które dostępne są przy każdym żądaniu. Połączenie pomiędzy sesją na serwerze a klientem realizowane jest poprzez ciasteczko, które przechowuje id sesji. Wydłużanie czasu trwania sesji nie jest najlepszym pomysłem, ze względu na większe prawdopodobieństwo przechwycenia sesji przez nie uprawnione osoby, tzw. session hijacking. Serwer nie potrafi rozróżnić uprawnionego klienta od nieuprawnionego i jedyna obroną przez przechwyceniem jest usuwanie sesji, które były nieaktywne przez określony czas. Mechanizm, który realizuje usuwanie nieaktywnych sesji nazywa się garbage collection. Każdorazowe użycie sesji powoduje zaktualizowane czasu jej ostatniego użycia. Sesja jest niszczona po przekroczeniu czasu od ostatniego użycia + czas trwania sesji. Domyślny czas trwania sesji to 1440 sekund, czyli 24 minuty.
Pierwszą zmienną, która nas interesuje jest session.gc_maxlifetime. Definiuje ona liczbę sekund, po których sesja zostanie uznana za nie aktywną i zostanie usunięta. Mechanizm garbage collection może być również uruchomiony przy wywołaniu funkcji session_start(). Prawdopodobieństwo jego uruchomienia wyliczane jest z dwóch kolejnych zmiennych: session.gc_probability / session.gc_divisor. Pierwsza zmienna domyślnie ustawiona jest na 1, druga na 100 co daje 1% szans na uruchomienie mechanizmu. Kolejną kwestią jest miejsce, w którym przechowujemy sesje na serwerze. Jeżeli użyjemy tego samego folderu dla wszystkich sesji to czasy ich trwania zostaną ustawione na czas trwania najkrótszej sesji. Musimy utworzyć nowy folder a ścieżkę do niego ustawić w zmiennej session.save_path.
function my_session_start($timeout = 24, $probability = 100, $cookie_domain = '/') { // czas trwania sesji na serwerze ini_set("session.gc_maxlifetime", $timeout); // czas życia ciasteczka po stronie klienta ini_set("session.cookie_lifetime", $timeout); // tworzymy osobny folder dla sesji o podobnym czasie trwania $path = ini_get("session.save_path") . DIRECTORY_SEPARATOR . "session_" . $timeout; if (!file_exists($path)) { if (!mkdir($path, 600)) { trigger_error("Błąd utworzenia katalogu sesji: '$path'", E_USER_ERROR); } } // wskazujemy ścieżkę do folderu ini_set("session.save_path", $path); // ustawienia dla mechanizmu garbage collection ini_set("session.gc_probability", $probability); ini_set("session.gc_divisor", 100); // uruchamiamy sesję session_start(); // możemy również, ustawiać czas sesji od nowa przy każdym odświeżeniu skryptu // poprzez każdorazowe ustawianie ciasteczka z nowym czasem życia if (isset($_COOKIE[session_name()])) { setcookie(session_name(), $_COOKIE[session_name()], time() + $timeout, $cookie_domain); } }
