Klasa sesji
Klasa sesji pozwala utrzymywać "stan" użytkowników i śledzić ich aktywności podczas gdy korzystają z Twojej strony. Klasa sesji przechowuje informacje sesyjne dla każdego użytkownika w postaci zserializowanej (i opcjonalnie szyfrowanej) w ciasteczku. Dla dodatkowego bezpieczeństwa, dane sesyjne mogą być również przechowywane w bazie danych - wtedy identyfikator sesji w ciasteczku jest porównywany z identyfikatorem sesji zapisanym w bazie danych. Domyślnie używane są tylko ciasteczka. Jeśli zdecydujesz się na wykorzystanie bazy danych, będziesz musiał stworzyć w niej tabelę do zapisu sesji, co opisano na dole tej strony.
Uwaga: Klasa sesji nie korzysta z natywnych sesji PHP. Generuje własne dane sesyjne, które są bardziej elastyczne dla deweloperów.
Uwaga: Nawet jeśli nie używasz szyfrowania sesji, musisz ustawić klucz szyfrowania w pliku konfiguracyjnym, który jest wykorzystywany do zapobiegania manipulowaniu danymi sesyjnymi.
Uwaga: Klasa Sesji polega na klasie Encryption, dlatego musisz mieć zainstalowane rozszerzenie Mcrypt na serwerze.
Inicjalizacja sesji
Zazwyczaj sesje będą uruchamiane przy pażdym załadowaniu strony, dlatego klasa sesji musi być zainicjalizowana w Twoim konstruktorze kontrolera lub ładowana automatycznie przez system. Przez większość czasu klasa sesji będzie działała w tle. Inicjalizacja sesji pozwoli na odczyt, tworzenie i aktualizację danych sesyjnych.
Aby zainicjować klasę sesji ręcznie w Twoim konstruktorze kontrolera, użyj funkcji $this->load->library:
$this->load->library('session');
Raz załadowany obiekt biblioteki Session będzie dostępny przez wywołanie $this->session
Jak działają sesje?
Kiedy strona jest ładowana, klasa sesji sprawdza czy istnieje poprawny identyfikator sesji w ciasteczku sesji użytkownika. Jeśli taki identyfikator nie istnieje (lub stracił swoją ważność) zostanie stworzona nowa sesja i zapisana w ciasteczku. Jeśli sesja istnieje, informacje w niej zawarte zostaną zaktualizowane i zapisane w ciasteczku. Przy każdej aktualizacji session_id zostanie zregenerowane.
Ważne jest abyś zrozumiał, że raz zainicjowana klasa sesji działa już automatycznie. Nie musisz nic robić, aby powyżej opisane działania miały miejsce. Możesz pracować z danymi zapisanymi w sesji lub dodawać do niej własne dane, ale proces odczytu, zapisu i aktualizacji sesji jest automatyczny.
Czym są dane sesyjne?
Sesja (w przypadku CodeIgnitera), to po prostu tablica, która zawiera następujące informacje:
- Unikalny identyfikator Session ID (jest to statystycznie losowy ciąg o bardzo silnej entropii, dla ułatwienia zahashowany przy użyciu funkcji MD5 i regenerowany (domyślnie) co pięć minut)
- Adres IP użytkownika
- Nazwa przeglądarki użytkownika (pierwsze 120 znaków identyfikujących przeglądarkę użytkownika)
- Znacznik czasu ostatniej aktywności.
Powyższe dane są przechowywane w ciasteczku w postaci zserializowanej w tym kształcie:
[array]
(
'session_id' => random hash,
'ip_address' => 'string - user IP address',
'user_agent' => 'string - user agent data',
'last_activity' => timestamp
)
Jeśli masz włączoną opcję szyfrowania, to zserializowana tablica szyfrowana jest przed zapisaniem w ciasteczku. Powoduje to, że dane stają się bardziej bezpieczne i tym samym bardziej odporne na niepowołany odczyt lub próby manipulacji. Więcej informacji na temat szyfrowania możesz znaleźć tytaj. Oczywiście klasa sesji zajmie się inicjalizacją i szyfrowaniem danych automatycznie.
Uwaga: Ciasteczka sesji są aktualizowane domyślnie co pięć minut, aby zredukować obciążenie procesora. Jeśli ciągle będziesz odświerzał stronę, zauważysz, że czas "ostatniej aktywności" zmienia się tylko jeśli upłynęło pięć minut lub więcej od czasu kiedy ciasteczko było ostatnio aktualizowane. Czas ten jest konfigurowalny poprzez zmianę wartości dla $config['sess_time_to_update'] w pliku system/config/config.php.
Zwracanie danych sesyjnych
Każda informacja z tablicy sesji jest dostępna poprzez użycie następującej funkcji:
$this->session->userdata('item');
Gdzie item jest indeksem tablicy, który chcesz otrzymać. Dla przykładu, aby uzyskać ID sesji musisz zrobić tak:
$session_id = $this->session->userdata('session_id');
Uwaga: Funkcja zwraca FALSE (boolean) jeśli wartość, do której chcesz dotrzeć nie istanieje.
Dodawanie własnych danych sesyjnych
Przydatnym aspektem tablicy sesyjnej jest to, że możesz dodać do niej własne dane, które będą przechowywane w ciasteczku użytkownika. Czemu chciałbyś to robić? Oto jeden z przykładów:
Załóżmy, że jeden z użytkowników loguje się na Twoją stronę. Kiedy zostanie uwieżytelniony, możesz dodać jego nazwę i adres email, do ciasteczka sesji - powodując, że dane te będą dostępne globalnie bez potrzeby uruchamiania zapytania do bazy danych, za każdym razem kiedy będziesz chciał z tych danych skorzystać.
Aby dodać własne dane do tablicy sesji, musisz przypisać tablicę zawierającą nowe dane do funkcji:
$this->session->set_userdata($array);
Gdzie $array jest tablica asocjacyjną zawierającą nowe dane. Oto przykład:
$newdata = array(
'username' => 'johndoe',
'email' => 'johndoe@some-site.com',
'logged_in' => TRUE
);
$this->session->set_userdata($newdata);
Jeśli chcesz dodać tylko jedną wartość na raz, to funkcja set_userdata() wspiera również tę składnię:
$this->session->set_userdata('nazwa', 'wartość');
Uwaga: Ciasteczka mogą przechowywać jedynie do 4KB danych, bądź więc ostrożny i nie przekrocz tej wartości. Proces szyfrowania w szczególności przyczynia się do tworzenia dłuższych ciągów niż te orginalne, dlatego bądź ostrożny i sprawdzaj ile danych przechowujesz.
Zwracanie wszystkich danych sesyjnych
Cała tablica danych sesyjnych może być zwrócona za pomocą funkcji:
$this->session->all_userdata()
Zwrócona tablica asocjacyjna wygląda w ten sposób:
Array ( [session_id] => 4a5a5dca22728fb0a84364eeb405b601 [ip_address] => 127.0.0.1 [user_agent] => Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; [last_activity] => 1303142623 )
Usuwanie danych sesyjnych
Tak samo jak funkcja set_userdata() może być wykorzystana do dodawania informacji do sesji, funkcja unset_userdata() może być użyta do ich usuwania, poprzez przypisanie klucza sesji. Dla przykładu, jeśli chcesz usunąć 'jakas_nazwa' z danych sesyjnych:
$this->session->unset_userdata('jakas_nazwa');
Do tej funkcji można równiez przypisać tablice asocjacyjną z wartościami do usunięcia.
$array_items = array('username' => '', 'email' => '');
$this->session->unset_userdata($array_items);
Flashdata
Codeigniter wspiera "flashdata", czyli dane sesyjne, które są dostępne jedynie do następnego żądania, a później są automatycznie usuwane. Ta opcja może być bardzo przydatna i zazwyczaj jest używana do przechowywania informacji i wiadomości (np.: "usunięto 2 rekordy").
Uwaga: Zmienne flash są poprzedzone wartością "flash_", unikaj więc tego prefixu we własnych nazwach dla zmiennych sesyjnych.
Aby dodać wartość flashdata:
$this->session->set_flashdata('item', 'value');
Możesz również przypisać tablicę do set_flashdata(), w ten sam sposób jak w przypadku set_userdata().
Aby odczytać wartości flashdata:
$this->session->flashdata('item');
Jeśli będziesz chciał "zatrzymać" wartości flashdata przez jeszcze jedno żądanie, możesz to zrobić za pomocą funkcji keep_flashdata().
$this->session->keep_flashdata('item');
Przechowywanie sesji w bazie danych
Z racji tego, że dane sesyjne przechowywane w ciasteczku zawierają identyfikator sesji, to o ile nie przechowujesz danych sesyjnych w bazie danych, nie ma tak naprawdę sposobu na zweryfikowanie poprawności sesji. Dla niektórych aplikacji, które wymagają tylko podstawowego bezpieczeństwa, lub nie wymagają go wcale, weryfikacja poprawności identyfikatora sesji może nie być potrzebna. Jeśli jednak wymagamy dobrego poziomu bezpieczeństwa, to taka weryfikacja jest konieczna. W innym wypadku istnieje niebezpieczeństwo, że stara sesja może zostać przywrócona poprzez modyfikację ciasteczka przez użytkownika.
Kiedy dane sesyjne są składowane w bazie danych, za każdym razem kiedy ważna sesja zostanie odnaleziona w ciasteczku, wykonywane jest zapytanie do bazy w celu weryfikacji sesji. Jeśli identyfikator sesji nie znajduje się w bazie danych - sesja jest usuwana. Identyfikatory sesji nie mogą być nigdy modyfikowane. Są generowane tylko w momencie kiedy sesja jest tworzona lub regenerowana.
W celu przechowywania sesji w bazie danych, musisz najpierw utworzyć odpowiednią tabelę. Oto podstawowa struktura (dla MySQL), wymagana przez klasę sesji:
Uwaga: Domyślnie tabela nosi nazwę ci_sessions, ale możesz ją nazwać jak tylko chcesz, jeśli tylko dokonasz odpowiedniej zmiany w pliku application/config/config.php. Jeśli utworzysz tabelę w bazie danych, możesz uaktywnić opcję przechowywania sesji w bazie danych, zmieniając pliku config.php zmienną:
$config['sess_use_database'] = TRUE;
W ten sposób klasa sesji będzie przechowywała zmienne sesyjne w bazie danych.
Upewnij się, czy określiłeś poprawnie nazwę dla tabeli w bazie danych:
$config['sess_table_name'] = 'ci_sessions';
Uwaga: Klasa sesji posiada wbudowany garbage collector, który usuwa przedawnione sesje - nie musisz więc pisać własnych procedur do tego celu.
Usuwanie sesji
Aby wyczyścić obecną sesję, wykonaj funkcję:
$this->session->sess_destroy();
Uwaga: Ta funkcja powinna być wywoływana jako ostatnia - nawet dane flashdata zostaną usunięte. Jeśli chcesz usunąć jedynie któryś z elementów sesji, użyj funkcji unset_userdata().
Ustawienia sesji
Wszystkie ustawienia konfiguracyjne sesji znajdziesz w pliku application/config/config.php:
Ustawienie | Domyślna wartość | Opcje | Opis |
---|---|---|---|
sess_cookie_name | ci_session | Brak | Nazwa jaką ma mieć ciasteczko sesji. |
sess_expiration | 7200 | Brak | Ilość sekund przez którą sesja będzie ważna. Domyślną wartością są 2 godziny (7200 sekund). Jeśli chcesz, aby sesja nie miała określonego czasu wygaśnięcia, ustaw tę wartość na zero: 0 |
sess_expire_on_close | FALSE | TRUE/FALSE (boolean) | Czy sesja ma wygasnąć automatycznie w momencie zamknięcia okna przegądarki. |
sess_encrypt_cookie | FALSE | TRUE/FALSE (boolean) | Czy szyfrować dane sesji. |
sess_use_database | FALSE | TRUE/FALSE (boolean) | Czy zapisywać dane sesji w bazie danych. Musisz stworzyć tabelę w bazie danych zanim zaczniesz używać tej opcji. |
sess_table_name | ci_sessions | Każda poprawna nazwa tabeli w języku SQL | Nazwa tabeli w bazie danych |
sess_time_to_update | 300 | Czas liczony w sekundach | Ta opcja określa jak często klasa sesji będzie się regenerować i tworzyć nowy id sesji. |
sess_match_ip | FALSE | TRUE/FALSE (boolean) | Czy sprawdzać zgodność numeru IP podczas odczytu danych sesyjnych. Zauważ, że niektórzy dostawcy internetu dynamicznie zmieniają adres IP. Jeśli nie chcesz aby sesja wygasała najprawdopodobniej warto ustawić tę opcję na wartość FALSE. |
sess_match_useragent | TRUE | TRUE/FALSE (boolean) | Czy sprawdzać zgodność nazwy przeglądarki podczas odczytu danych sesyjnych. |