Po wielu dochodzenia w sprawie, w naszej firmie, doszedłem do tego wyniku, mam nadzieję, że to pomaga, przede wszystkim tutaj jest nasze wymagania środowiskowe:
- PHP: 5.3.3
- laravel: 4,1
- OS: CentOS 6 na serwerze i OS X Mavericks w środowisku programistycznym
- APACHE 2
- mysql 05.06.19
- REDIS: 2.4.10
- PREDIS. 0,8 *
pierwsze wydaje się, że wyjątek TokenMistmatch występuje zróżnicowane inaczej warunki, prawie zbadałem ich wszystkich i byłem w stanie rozwiązać niektóre z nich, niektóre zależą od logiki stojącej za sesją, a niektóre mogą być błędami. Poniżej wyjaśnię każdą sytuację, z którą się spotkałem.
1. Przeterminowane sesje
Powiedzmy skonfigurowaniu sesji przez 3 godziny użytkownik otwiera formularz iz jakiegoś powodu zostawia komputer (coraz filiżankę kawy), więc po 3 godzinach, gdy sesja wygasła, próbuje przesłać formularz i otrzymuje wyjątek od tokena. właśnie dlatego wszyscy raz na jakiś czas otrzymują błąd symboliczny, niezależnie od tego, na ile stabilna jest ta aplikacja, mogę sobie wyobrazić 2 sposoby, aby temu zapobiec i odnawiają plik cookie sesji przy użyciu ajaxa w odpowiednim czasie lub wydłużają czas wygaśnięcia sesji przez znaczną ilość czasu.
2.Zgłoszenia współbieżne w przypadku wygaśnięcia sesji
Czasami na ładowanie pierwszej strony przychodzą równoczesne żądania, na przykład użytkownik ma dwie różne karty otwarte na chromie i po ponownym otwarciu chrome chrome wysyła żądania jednocześnie lub możesz mieć wiele współbieżnych wniosek ajax na ładunek pierwszej strony aplikacji. więc pamiętaj, że plik cookie sesji jest odbierany po otrzymaniu pierwszej odpowiedzi, ale możesz wysłać następne żądanie, zanim to się stanie, a zatem otrzymasz nową sesję (nowy plik cookie) na każde żądanie, co może doprowadzić do wyjątku tokena, jeśli któryś z tych wnioski wypełnia formularz. możesz zapobiec temu scenariuszowi w oparciu o jego źródło, na przykład jeśli zapytanie ajax powoduje problem i nie używasz sesji w odpowiedziach ajaxowych, możesz wyłączyć wysyłanie pliku cookie sesji, jeśli żądanie jest ajaxowe, w drugim scenariuszu (klikając przesłać przycisk kilka razy) można łatwo wyłączyć przycisk po jego przesłaniu.
3. jednoczesnych żądań przy logowaniu
Gdy nastąpiło logowanie, laravel ze względów bezpieczeństwa zmienia identyfikator sesji, skopiuj dane sesji i niszczy ostatniej sesji tak powiedzmy z jakiegoś powodu po zalogowaniu jednoczesnych żądań stało się (kilkakrotne kliknięcie przycisku logowania), aby identyfikator sesji był wielokrotnie odtwarzany i ZNISZCZA ostatnie wygenerowane sesje po stronie serwera, ponieważ niektóre z tych żądań nadal używają wcześniejszego identyfikatora sesji (który już nie istnieje po stronie serwera)) prowadzi to do regeneracji tokenu CSRF, pamiętaj, że zwykle laravel nie regeneruje tokena przy logowaniu, jeśli może znaleźć token w sesji gościa (niezalogowanej), ale w tym przypadku jako gue st sesja jest niszczona, w wyniku czego zregeneruje token i może doprowadzić do wyjątku tokena w innych żądaniach, które używają oryginalnego tokena. należy również zauważyć, że nie tylko ten problem może powodować wyjątek tokenowy, ale może również spowodować wylogowanie użytkownika po jednym żądaniu, ponieważ żądania równoczesne mogą zmienić zalogowaną sesję. I rozwiązać ten problem poprzez zmianę jednego wiersza w kodzie laravel w Illuminate\Auth\Guard:updateSession
:
protected function updateSession($id)
{
$this->session->put($this->getName(), $id);
//$this->session->migrate(true);
$this->session->migrate()
}
przechodząc wierny metodzie migrować sklepu sesji spowoduje zniszczenie sesji na serwerze po migracji, więc teraz dane będą pozostaną na serwerze i zostaną zniszczone w czasie ich wygaśnięcia, a nie na tej prośbie, a rozwiąże to problem. Nie wiem, czy możemy to nazwać błędem w laravel, ale myślę, że możemy wymyślić lepsze rozwiązanie.
4. Przeglądarki
Po zbadaniu dzienniki okazało się, że niektóre z tych tokenów wyjątkami były z powodu przeglądarka użytkownika nie zaakceptowaniem cookie sesji, widziałem go najbardziej na iOS Safari, wierzę, że to coś, czego nie możemy z tym zrobić.
5. Redis bug
Niektóre z wyjątków tokenów na naszej sever z powodu REDiS jakiegoś powodu laravel nie mógł odczytać dane sesji z serwera Redis po otwarciu sesji więc byłoby doprowadzić do regeneracja tokenu CSRF. działo się to przypadkowo na naszym serwerze, więc próbowałem zmienić sterownik sesji i ten typ wyjątków zniknął. Próbowałem sterowników baz danych, apc i plików i żaden nie spowodował tego problemu. Nie znalazłem jeszcze przyczyny błędu, ale myślę, że może to być błąd z redis lub biblioteką predis. (jak wiesz, laravel 4.1 nie używa najnowszej wersji predis z powodu problemów ze zgodnością).
Okej, to są moje doświadczenia z ostatnich dwóch miesięcy pracy nad tym problemem.Mam nadzieję, że może to zmienić Twój punkt widzenia dotyczący rozwiązania tego problemu, najważniejsze jest to, że wyjątek tokena nie występuje z jednego powodu, że może być wynikiem wielu problemów. proszę, podziel się ze mną, jeśli miałeś podobny incydent lub masz coś nowego.
Może to być pomocne http://stackoverflow.com/questions/27938186/ laravel-only-allow-one-session-per-user-at-time – astroanu
@astro to po prostu usuwa ostatnią sesję, która powoduje ten sam problem. jakiś pomysł na generowanie tego samego identyfikatora sesji w bezpieczny sposób? – Amir
Zgaduję, że jedyną metodą byłoby rozszerzenie klasy sesji i napisanie własnego? http://laravel.com/docs/4.2/extending#session – astroanu