Czy żądania AJAX zachowują informacje o sesji PHP?

154

Gdybym miał użytkownika zalogowanego na mojej stronie, mając zapisany jego identyfikator $_SESSION, i ze swojej przeglądarki kliknął przycisk „Zapisz”, co spowodowałoby wysłanie żądania AJAX do serwera. Czy jego $_SESSIONi pliki cookie zostaną zachowane w tym żądaniu i czy mogę bezpiecznie polegać na tym, że identyfikator jest obecny w $_SESSION?

Kliknij opcję Głos za
źródło

Odpowiedzi:

191

Odpowiedź brzmi tak:

Sesje są obsługiwane po stronie serwera. Jeśli chodzi o serwer, nie ma różnicy między żądaniem AJAX a zwykłym żądaniem strony. Oba są żądaniami HTTP i oba zawierają informacje o plikach cookie w nagłówku w ten sam sposób.

Ze strony klienta te same pliki cookie będą zawsze wysyłane do serwera, niezależnie od tego, czy jest to zwykłe żądanie, czy żądanie AJAX. Kod Javascript nie musi robić nic specjalnego ani nawet być tego świadomy, działa tak samo, jak w przypadku zwykłych żądań.

thomasrutter
źródło
10
Kontynuacja: serwer może ustawić HttpOnlyflagę podczas ustawiania pliku cookie, co oznacza, że ​​Twój Javascript nie będzie w stanie zobaczyć pliku cookie. Jednak plik cookie będzie nadal wysyłany zarówno w przypadku żądań AJAX, jak i zwykłych żądań stron i nadal będzie działał dokładnie tak samo. Twój Javascript po prostu go nie zobaczy document.cookie.
thomasrutter
Jeśli raportowanie błędów PHP jest włączone, możesz otrzymać błąd sesji zwrócony wraz z odpowiedzią AJAX. Warning: session_write_close(): Failed to write session data (user)Ostatnio sporadycznie otrzymuję błąd w projekcie, ale tylko wtedy, gdy żądanie AJAX ma miejsce podczas ładowania pozostałej części strony. Używam bazy danych MySQL dla danych sesji i możliwe, że żądanie strony głównej blokuje tę tabelę, uniemożliwiając dostęp do niej żądaniu AJAX.
Buttle Butkus
@ButtleButkus, który brzmi jak problem w kodzie po stronie serwera i jestem pewien, że ludzie będą chętni do pomocy, jeśli zadasz to jako własne pytanie. Nie powinieneś otrzymywać tego błędu tylko dlatego, że używasz MySQL do sesji, ponieważ nie powinien on blokować się w sposób, który zakończyłby się niepowodzeniem z błędem. Może to być problem związany z nasycaniem połączeń MySQL lub inny niepowiązany problem.
thomasrutter
Dzieje się to na wędrownej maszynie, więc połączenia MySQL powinny być nasycone. Zdecydowanie opublikuję pytanie, jeśli wkrótce nie będę mógł tego rozgryźć.
Buttle Butkus
23

Jeśli plik PHP żądania AJAX zawierają session_start()informacje o sesji, zostaną zachowane. (zablokowanie żądań znajduje się w tej samej domenie)

Ólafur Waage
źródło
2
w istocie o tym zapomniałem :-)
sivann
23

To, co naprawdę masz, to: czy pliki cookie są wysyłane z żądaniem AJAX? Zakładając, że żądanie AJAX dotyczy tej samej domeny (lub w ramach ograniczeń domeny pliku cookie), odpowiedź brzmi tak. Zatem żądania AJAX z powrotem do tego samego serwera zachowują te same informacje o sesji (zakładając, że wywoływane skrypty wysyłają sesję_start (), jak każdy inny skrypt PHP, który chce uzyskać dostęp do informacji o sesji).

cletus
źródło
1
Mogę się mylić, ale myślałem, że nie można nawet wysyłać żądań ajax do innych domen (z wyłączeniem subdomen)?
Emil H,
Możesz oszukiwać za pomocą dynamicznej sztuczki skryptowej. Jednak nigdy go nie męczyłem.
cletus
1
Tak, żądania AJAX nie mogą być wysyłane do innych domen. Możesz jednak dynamicznie wstawić tag <script> na stronę i ustawić jego src na adres URL spoza domeny, który odzwierciedla kod JavaScript.
Kliknij „Za głosowaniem”
1
Żądania ajax nie mogą być wysyłane do innych domen. ale możesz utworzyć proxy w swoim kodzie php. Żądanie ajax do proxy, żądanie proxy do innej domeny.
Peter Long
2
Tylko uwaga ... żądania AJAX można przesyłać między domenami, ale tylko wtedy, gdy typ odpowiedzi to jsonp. Robię to cały czas.
Objawienie Pańskie
8

Cóż, nie zawsze. Korzystając z plików cookie, jesteś dobry. Jednak pytanie „czy mogę bezpiecznie polegać na obecności identyfikatora” skłoniło mnie do rozszerzenia dyskusji o ważny punkt (głównie w celach informacyjnych, ponieważ liczba odwiedzających tę stronę wydaje się dość wysoka).

PHP można skonfigurować tak, aby utrzymywał sesje przez przepisywanie adresów URL zamiast plików cookie. ( Jak to jest dobre lub złe (<- zobacz np. Najwyższy komentarz) to osobne pytanie , teraz trzymajmy się aktualnego, z tylko jedną uwagą boczną: najważniejszy problem z sesjami opartymi na adresach URL - rażący widoczność samego identyfikatora sesji - nie jest to problem z wewnętrznymi wywołaniami Ajax; ale potem, jeśli jest włączony dla Ajax, jest włączony także dla reszty witryny, więc tam ...)

W przypadku sesji przepisywania adresów URL (bez plików cookie) wywołania Ajax muszą same zadbać o to, aby ich adresy URL żądań były odpowiednio spreparowane. (Lub możesz wdrożyć własne niestandardowe rozwiązanie. Możesz nawet uciec się do utrzymywania sesji po stronie klienta , w mniej wymagających przypadkach.) Chodzi o wyraźną ostrożność potrzebną do ciągłości sesji, jeśli nie używasz plików cookie:

  1. Jeśli wywołania Ajax po prostu wyodrębniają adresy URL dosłownie z HTML (otrzymane z PHP), powinno to być OK, ponieważ są już ugotowane (umm, ugotowane).

  2. Jeśli muszą samodzielnie zestawić identyfikatory URI żądań, identyfikator sesji należy dodać do adresu URL ręcznie. (Sprawdź tutaj lub źródła stron generowane przez PHP ( z włączonym przepisywaniem adresów URL ), aby zobaczyć, jak to zrobić.)


Z OWASP.org :

W efekcie aplikacja internetowa może korzystać z obu mechanizmów, plików cookie lub parametrów adresu URL, a nawet przełączać się z jednego na drugi (automatyczne przepisywanie adresu URL), jeśli spełnione są określone warunki (na przykład istnienie klientów internetowych bez obsługi plików cookie lub gdy pliki cookie nie są zaakceptowane ze względu na obawy dotyczące prywatności użytkownika).

Z postu na forum Ruby :

Podczas korzystania z php z plikami cookie, identyfikator sesji zostanie automatycznie wysłany w nagłówkach żądań, nawet w przypadku Ajax XMLHttpRequests. Jeśli używasz lub zezwalasz na sesje php oparte na adresach URL, będziesz musiał dodać identyfikator sesji do każdego adresu URL żądania Ajax.

Sz.
źródło
Jakieś wiarygodne statystyki dotyczące liczby osób, dla których wyłączono pliki cookie sesji ? (Nie znalazłem żadnego. Tylko w Javascript: wydaje się, że około 2% w USA / Europie i ~ 1,2% średniej światowej.)
Sz.
Identyfikatory sesji w adresie URL są przestarzałą i niezabezpieczoną praktyką. W dzisiejszej sieci nikt nie powinien zakładać, że może surfować po wyłączonych plikach cookie i nadal logować się na stronach internetowych, na których posiada konto. Jeśli jeden z gości ma wyłączone pliki cookie, prawdopodobnie można bezpiecznie założyć, że albo a) konkretnie nie chce mieć możliwości logowania się w żadnej witrynie ze względu na ochronę prywatności; lub b) zrobili to przypadkowo i teraz nie mogą zalogować się do żadnej witryny, nie tylko do Twojej.
thomasrutter
3

Bardzo ważne jest, aby żądania AJAX zachowywały sesję. Najłatwiejszym przykładem jest, powiedzmy, próba wykonania żądania AJAX dla panelu administracyjnego. Oczywiście zabezpieczysz stronę, do której wysyłasz żądanie, aby nie była dostępna dla innych, którzy nie mają sesji, którą otrzymujesz po zalogowaniu administratora. Ma sens?

Bogdan Constantinescu
źródło
0

Jedną rzeczą, na którą należy uważać, szczególnie jeśli używasz frameworka, jest sprawdzenie, czy aplikacja odtwarza identyfikatory sesji między żądaniami - wszystko, co zależy bezpośrednio od identyfikatora sesji, spowoduje problemy, chociaż oczywiście reszta danych w sesja pozostanie nienaruszona.

Jeśli aplikacja odtwarza identyfikatory sesji w ten sposób, możesz skończyć z sytuacją, w której żądanie AJAX w efekcie unieważnia / zastępuje identyfikator sesji na stronie żądającej.

Jan
źródło
0

To właśnie robią frameworki, np. Jeśli zainicjujesz sesję w kontrolerze frontowym lub skrypcie boostrap, nie będziesz musiał przejmować się jego inicjalizacją ani dla kontrolerów stron, ani dla kontrolerów ajax. Frameworki PHP nie są panaceum, ale robią tak wiele przydatnych rzeczy!

AlexA
źródło
0

umieść swoje session () auth na wszystkich stronach serwera akceptujących żądanie ajax:

if(require_once("auth.php")) {

//run json code

}

// do nothing otherwise

to chyba jedyny sposób, w jaki kiedykolwiek to zrobiłem.

brianabee7
źródło