Czy należy unikać zmiennych sesji?

36

Kiedyś w dużej mierze polegałem na zmiennych sesji, ale ostatnio stwierdziłem, że wiele z nich jest niepotrzebnych, zamiast tego używam takich parametrów, jak parametry ciągu zapytania.

Mój kolega nie chce używać zmiennych sesji. Czy jest to realistyczny cel i czy należy unikać zmiennych sesji z jakichkolwiek praktycznych powodów? Czy można całkowicie uniknąć zmiennych sesji (z wyjątkiem sesyjnych plików cookie umożliwiających logowanie) i czy spowodowałoby to lepsze projekty?

Niektóre z powodów, dla których mój kolega nie korzysta z nich:

  • Nietypowy charakter zmiennych sesji
  • Limit czasu sesji powodujący utratę stanu
  • Globalny zakres zmiennych sesji
  • Serwery równoważenia obciążenia tracą sesje (specyficzne dla .Net?)
  • Ponowne uruchamianie pul aplikacji / serwerów
  • Są niepotrzebne
Tjaart
źródło
3
using things like query string parameters instead- W tym jednym przypadku zawsze używaj parametrów ciągu zapytania, jeśli to możliwe. Używanie sesji dla tego typu parametru jest delikatne i może wprowadzać dziwne błędy, gdy użytkownicy mają otwarte wiele kart.
Izkata
2
osobiste rekomendacje - nie bierz żadnej porady od swojego kolegi, ponieważ wyraźnie nie wie o czym mówi. Przekroczenia limitu czasu sesji? Czy nie zdaje sobie sprawy, że czas trwania sesji jest kontrolowany przez aplikację internetową?
GrandmasterB
2
@GrandmasterB Ahem. Albo nie wie, co robią, albo został spalony przez każdy z tych pocisków w trakcie swojej kariery (ja trafiłem około 4 z nich) i zna bardziej odpowiednie sposoby radzenia sobie ze stanem tymczasowym.
Ed James
Czy ktoś mógłby wyjaśnić związek między stanem sesji a otwarciem wielu kart? Czy po otwarciu nowej karty zawiera ona stan z poprzedniej karty? Dzięki.
Ray

Odpowiedzi:

41

Jeśli w aplikacji masz zmienną sesji, zadaj sobie następujące pytanie:

Jaką wartość chcę mieć po kliknięciu przycisku Wstecz w przeglądarce?

Jeśli odpowiedź brzmi „bieżąca wartość”, zmienne sesji mogą być przydatne. Przykładem może być koszyk z zakupami: nie oczekujesz, że rzeczy zostaną usunięte z koszyka podczas przeglądania historii. Zawsze jest w obecnym stanie.

Jeśli odpowiedź brzmi „poprzednia wartość”, nie powinieneś używać zmiennych sesji. Złe zastosowania, które widziałem, obejmują przekazywanie parametru między stronami. Jeśli kliknę przycisk Wstecz, aby wrócić do strony, strona niekoniecznie uzyska prawidłowy parametr. Ponadto, jeśli otworzę dwie karty, jak zachowa się moja witryna?

Właściwe zachowanie przycisku Wstecz nie jest bynajmniej wszechstronne, ale pomaga myśleć o witrynie jako aplikacji bezstanowej. Zasadniczo uważam, że odpowiednie zastosowania zmiennych sesji są nieliczne i dalekie.

Tim
źródło
Zgadzam się. Kiedy pomyślisz o pożądanej semantyce z wieloma kartami, zwykle staje się oczywiste, czy zmienne sesji lub parametry żądania są właściwym wyborem.
CodesInChaos
Widziałem dokładnie tego rodzaju błędy w zmiennych sesji i sam nauczyłem się na własnej skórze.
Tjaart,
Kiedy użytkownik naciśnie przycisk Wstecz, czy oczekuje, że przedmioty pozostaną w koszyku do czasu wygaśnięcia sesji, czy też chce, aby przedmioty pozostały do ​​momentu ich wyjęcia? Użycie innego mechanizmu utrwalania (np. Bazy danych) pozwoliłoby na przetrwanie poza pojedynczą sesją, a przycisk Wstecz nadal działałby zgodnie z oczekiwaniami użytkownika.
Lawtonfogle
25

Protokół HTTP jest bezstanowy. Sesje są sposobem na zachowanie stanu klienta w żądaniach HTTP. Możesz to zrobić za pomocą wbudowanej obsługi sesji platformy lub zrób to sam z parametrami ciągu zapytania. Tak czy inaczej, dla wielu zadań konieczna jest pewna koncepcja sesji.

Twój kolega prawdopodobnie nie lubi określonej implementacji lub nie używa sesji zgodnie z przeznaczeniem. Jeśli chcesz zachować informacje o określonym połączeniu klienta w żądaniach HTTP, potrzebujesz trwałej formy sesji.

Następujące problemy są specyficzne dla implementacji:

Nietypowy charakter zmiennych sesji

Globalny zakres zmiennych sesji

Serwery równoważenia obciążenia tracą sesje

Ponowne uruchamianie pul aplikacji / serwerów

Na przykład najczęściej pracuję w PHP i przechowuję informacje o sesji w relacyjnej bazie danych. Więc moje zmienne sesji są wpisane. Równoważenie obciążenia i ponowne uruchomienie serwera nie powodują żadnych problemów z sesją.

Ten jest bardziej interesujący:

Limit czasu sesji powodujący utratę stanu

Sesje są najczęściej przechowywane za pomocą plików cookie. Mogą one zostać usunięte przez klienta w dowolnym momencie. Ale można je również zachować za pomocą parametru ciągu zapytania, a zatem nigdy nie przekraczać limitu czasu na kliencie. Limit czasu serwera zależy od Ciebie. Więc nawet ten problem dotyczy konkretnej implementacji.

Nie odrzucajmy całej koncepcji sesji tylko dlatego, że nie lubimy konkretnej implementacji. Każda dobra struktura aplikacji internetowej ułatwi prawidłowe korzystanie z sesji, aby zachować loginy użytkownika lub zachować wszystko inne, co jest związane z bieżącą wizytą użytkownika. Rekord bazy danych użytkownika może (i powinien) być używany do przechowywania rzeczy specyficznych dla niego po zalogowaniu. Jednak użytkownicy anonimowi mogą mieć tymczasowe informacje, które warto zachować w ich sesji, takie jak krótka lista ostatnio odwiedzanych stron lub preferencja ukryj ogłoszenie, które już widzieli. Zasadniczo tylko mniejsze informacje tymczasowe są odpowiednie do przechowywania sesji.

Matt S.
źródło
Szczerze mówiąc miałem ograniczone doświadczenie z frameworkami poza .Net. .Net przestaje wymuszać wartość limitu czasu sesji. Zmienne sesji również wyświetlają kod po stronie serwera jako słownik bez typów. Zazwyczaj i tak zawijam ten słownik do poprawnie wpisanych klas, więc też nie widzę w tym problemu. Wspomniałeś, że przechowujesz informacje o sesji w bazie danych. W ASP .Net pamięć jest przetwarzana w inny sposób, albo w kliencie .Net, w bazie danych (zarządzany automatycznie) lub w oddzielnej usłudze systemu Windows.
Tjaart,
Czy możesz podać kilka przykładów zamierzonych celów sesji?
Tjaart,
@ Tjaart: Rozszerzyłem nieco ostatni akapit. Mam nadzieję, że to pomaga.
Matt S
14

Inni przedstawili wiele dobrych punktów (których nie będę powtarzał), ale jest jeden aspekt techniki twojego kumpla, który nie został jeszcze omówiony: bezpieczeństwo .

Nie można wiedzieć, jakie luki otwierasz, nie patrząc na kod, ale oto kilka rzeczy, które mogę wymyślić z góry.

  • Naprawianie sesji : potężny atak, który jest nieco łatwiejszy, jeśli użytkownik może po prostu kliknąć link, który już zawiera niezbędne informacje w adresie URL (zamiast próbować zmusić użytkownika do korzystania z komputera, na którym odpowiednio skonfigurowano pliki cookie).
  • Wstrzyknięcie SQL (lub inne złośliwe dane wejściowe) : Nigdy nie ufaj niczego, co pochodzi od użytkownika. Zaletą zmiennych sesji jest to, że nigdy nie opuszczają serwera, dlatego użytkownik nie może ich bezpośrednio zmienić. Chociaż przed odłożeniem ich do sesji powinieneś zdezynfekować dane , zawsze możesz ufać wartościom, które później otrzymasz. Jeśli wszystko jest przekazywane przez ciąg zapytania, masz DUŻO weryfikacji, co musisz zrobić, aby upewnić się, że nie akceptujesz złośliwych danych wejściowych.
  • Uszkadzanie danych przy użyciu sfałszowanych danych wejściowych : Jak w przypadku wstrzyknięcia SQL, ile danych przesyłasz w tę iz powrotem? Jak ważne jest to? Czy mogę zmienić zachowanie aplikacji, zmieniając wartość w ciągu zapytania? Czy mogę uszkodzić dane na serwerze, zmieniając wartości? Jeśli uda mi się uszkodzić dane na serwerze, czy wpłynie to na innych użytkowników? (Jeśli Twoja odpowiedź brzmiała „nie”, moja odpowiedź brzmi „jesteś pewien? Masz wiele miejsc, które musisz sprawdzić”).

Wszystko to może się zdarzyć podczas korzystania z Sesji, ale mogą być znacznie łatwiejsze, jeśli twój kumpel nie wie, co robi.

riwalk
źródło
2

Zmienne sesji są w pewnym stopniu podobne do starych podstawowych zmiennych globalnych. Obowiązkiem użytkownika jest ich śledzenie, co jest w nim, ich zakres i sposób użycia; podobnie jak w starych wersjach BASIC. Biorąc to pod uwagę, dlaczego ktoś całkowicie pomija korzystanie z mechanizmu, który jest oczywiście zaprojektowany jako integralna i bardzo ważna część modelu programowania (ASP, MVC itp.)?

Jedyną złą rzeczą, na którą natknąłem się podczas używania zmiennych Session, jest to, że obciąża cię to, że je śledzisz, upewniasz się, że są zapełniane danymi źródłowymi i usuwają je.

Czy nie to robimy, gdy programujemy w jakikolwiek sposób?

Prochowiec
źródło
1

Kiedyś myślałem jak twój kolega z powodu złych doświadczeń, które miałem podczas debugowania problemów związanych ze zmiennymi sesji, które były po prostu niekompetencją z mojej strony. Tak, można do pewnego stopnia obejść się bez zmiennych sesji, używając ciągów zapytań, ukrytych pól w formularzach i innych rzeczy. Jednak bardzo szybko staje się to kłopotliwe, jeśli twoja aplikacja ma coś poza najbardziej podstawowym przepływem logicznym w celu ustalenia stanu. Istnieje również ryzyko związane z bezpieczeństwem związane z wyświetlaniem wewnętrznych działań aplikacji za pomocą ciągów zapytań i ukrytych pól, z których każdy może służyć jako wektory ataku.

Podczas pracy ze zmiennymi sesyjnymi musisz tylko śledzić, kiedy zostaną ustawione i rozbrojone, ponieważ to określi przepływ logiczny aplikacji. To jest jak zarządzanie pamięcią w języku takim jak C.

Zauważ, że to tylko z mojego doświadczenia w pracy z PHP nad stosunkowo małym projektem bez ram, rzeczy mogą się różnić na innych platformach, ale myślę, że nadal obowiązuje ogólna zasada.

primehunter326
źródło
2
Jak uzyskać wiele semantyki na wielu kartach podczas używania sesji dla stanu zaangażowanego w przepływ sterowania? Sesje działają dobrze w przypadku logowania i ustawień, takich jak właściwości, ale nie mają właściwej semantyki do większości innych zastosowań.
CodesInChaos
Nie jestem pewien, czy to, co napisałem, było oparte na moim, co prawda, ograniczonym doświadczeniu w tworzeniu aplikacji internetowej opartej na bazie danych w PHP / MySQL. Jak zazwyczaj obsługiwane są różne karty w przeglądarkach (zakładam, że o to ci chodzi)?
primehunter326
@ primehunter326 Z parametrami trasy lub ciągami zapytań lub ukrytymi polami formularza.
Casey
0

Jak już wspomniano, HTTP jest bezstanowy, a zmienna sesji to łamie. Bezstanowy projekt HTTP pomaga buforować zasoby. Dla zasobów, które są publicznie dostępne.

Możliwe jest zaprojektowanie strony internetowej bez zmiennej sesji, ale jest to trudniejsze. Najtrudniejszym (IMHO) jest fantazyjne logowanie / wylogowanie, schematy uwierzytelniania HTTP nie zapewniają narzędzi potrzebnych do uwierzytelnienia za pomocą formularza HTML (możesz zhakować coś za pomocą javascript - XHR na https: // untel: [email protected] ) i jeszcze trudniej się wylogować i być kompatybilnym z wieloma przeglądarkami. była dyskusja na temat list maillingowych w3 na ten temat, ale jeśli dobrze pamiętam, pomysł został odrzucony.

Przez resztę powinieneś być w stanie żyć bez zmiennych sesji. Będziesz mieć pewien stan w bazie danych, plikach lub gdziekolwiek, ale użycie zmiennych Session powinno być rzadkie.

Jeśli użytkownik ma koszyk, jest to sesja zmienna tylko wtedy, gdy użytkownik ma mieć możliwość przeglądania na dwóch komputerach / przeglądarce bez udostępniania koszyka.

Mathieu
źródło