Żądanie pocztowe w Laravel - Błąd - 419 Przepraszamy, sesja / 419 Twoja strona wygasła

88

Zainstalowałem Laravel 5.7

Dodano formularz do pliku \resources\views\welcome.blade.php

<form method="POST" action="/foo" >
    @csrf
    <input type="text" name="name"/><br/>
    <input type="submit" value="Add"/>
</form>

Dodano do pliku \routes\web.php

Route::post('/foo', function () {
    echo 1;
    return;
});

Po wysłaniu żądania POST:

419 Przepraszamy, sesja wygasła. Odśwież i spróbuj ponownie.

W wersji 5.6nie było takiego problemu.

Thủ Thuật Máy Tính
źródło
Czy próbowałeś dodać przekierowanie? Zamiast return;ciebie możesz zadzwonić return redirect()->back();. Z tego, co widzę, aplikacja nie ma nic do zrobienia po wysłaniu żądania. Może po przetworzeniu żądania możesz przekierować go do widoku.
dcangulo
1
Mam ten sam problem. Kiedy przejść na sesji bazy danych tak się dzieje i kiedy wrócić do filena SESSION_DRIVERw .envto działa dobrze. Dlaczego sesja oparta na bazie danych nie działa.
Junaid Qadir
Skopiowałem twój dokładny kod do nowej instalacji laravel 5.7. Zadziałało. Problem występuje gdzie indziej.
Kyle Wardle
ten problem z powodu problemu z tokenem. Próbowałem uruchomić ten sam kod, ale nie pojawia się żaden błąd. Powinieneś podać więcej informacji, takich jak sterownik sesji, wyświetlanie wartości _token w formularzu. Możesz także zdebugować się w tej vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.phplinii pliku 67, aby dowiedzieć się dlaczego
bangnokia,
1
Zdałem sobie sprawę, że użyłem sessionsstołu do innego celu. Po zmianie nazwy tabeli na bardziej dopasowaną oraz uruchomieniu artisan session:tablei odświeżeniu migracji wszystko działa dobrze
Junaid Qadir,

Odpowiedzi:

113

Przed przeczytaniem poniżej upewnij się, @csrfczy {{ csrf_field() }}w swojej formie jak

<form method="post">
@csrf <!-- {{ csrf_field() }} -->
... rest of form ...
</form>

W larvel pojawia się komunikat o błędzie Session Expired lub 419 Page Expired, ponieważ gdzieś weryfikacja tokenu csrf kończy się niepowodzeniem, co oznacza, że App\Http\Middleware\VerifyCsrfToken::classoprogramowanie pośredniczące jest już włączone. W formie @csrfdyrektywa ostrza została już dodana, co również powinno być w porządku.

Następnie kolejnym obszarem do sprawdzenia jest sesja. csrfWeryfikacja tokena jest bezpośrednio związany z sesją, więc warto sprawdzić, czy kierowca sesja działa, czy nie, taki jak niepoprawnie skonfigurowanego Redis może powodować problem.

Może możesz spróbować zmienić sterownik / oprogramowanie sesji z .envpliku, obsługiwane sterowniki są podane poniżej

Obsługiwane sterowniki sesji w Laravel 5, Laravel 6 i Laravel 7 (Doc Link)

  • file - sesje są przechowywane w pamięci / ramach / sesjach.
  • cookie - sesje są przechowywane w bezpiecznych, zaszyfrowanych plikach cookie.
  • database - sesje są przechowywane w relacyjnej bazie danych.
  • memcached/ redis- sesje są przechowywane w jednym z tych szybkich sklepów opartych na pamięci podręcznej.
  • array - sesje są przechowywane w tablicy PHP i nie będą utrwalane.

Jeśli twój formularz działa po przełączeniu sterownika sesji, oznacza to, że coś jest nie tak z tym konkretnym sterownikiem, spróbuj naprawić błąd z tego miejsca.

Możliwe scenariusze podatne na błędy

  • Prawdopodobnie sesje oparte na plikach mogą nie działać z powodu problemów z uprawnieniami do /storagekatalogu (szybkie wyszukiwanie w Google przyniesie Ci rozwiązanie), pamiętaj również, że umieszczenie 777 dla katalogu nigdy nie jest rozwiązaniem.

  • W przypadku sterownika bazy danych połączenie z bazą danych może być nieprawidłowe lub sessionstabela może nie istnieć lub być nieprawidłowo skonfigurowana (potwierdzono, że błędna część konfiguracji jest problemem zgodnie z komentarzem @Junaid Qadir).

  • redis/memcached konfiguracja jest nieprawidłowa lub jest manipulowana przez inny fragment kodu w systemie w tym samym czasie.

Dobrym pomysłem może być wykonanie php artisan key:generatei wygenerowanie nowego klucza aplikacji, który z kolei opróżni dane sesji.

Wyczyść pamięć podręczną przeglądarki TRUDNE. Uważam, że Chrome i Firefox są winowajcami bardziej, niż pamiętam.

Przeczytaj więcej o tym, dlaczego klucze aplikacji są ważne

Shobi
źródło
1
Czasami jest tak, że przeglądarki, głównie Chrome, nie umieszczają wartości sesji Set-Cookie, ponieważ jest źle sformułowana lub niestandardowa. Tak więc Laravel nie znajdzie żadnej istniejącej wartości sesji z żądania HTTP do porównania z _tokenwartością otrzymaną z FORMULARZA. Unikaj używania SESSION_DOMAIN=...adresów IP, które Chrome i specyfikacje plików cookie HTTP uważają za niezabezpieczone.
KeitelDOG
Mam ten sam problem, ale ciągle nie otrzymuję błędu. Po prostu zdarza się to od czasu do czasu. Myślę, że oznacza to, że nie ma problemu ze sterownikiem sesji, ponieważ działa 99% czasu. Ale prowadzę aplikację na żywo i od czasu do czasu otrzymuję skargi od klientów. Jest to jednak bardzo rzadkie. Używam sterownika sesji plików. Czy ktoś wie, dlaczego tak się dzieje w moim przypadku? Dziękuję
TheAngelM97
@ TheAngelM97 Możesz łatwo odtworzyć ten błąd, przechodząc do strony logowania lub rejestracji. Nie rób nic przez może dłużej niż 30 minut. Następnie, gdy klikniesz Prześlij, 419 Page Expiredpojawi się. Ze względu na użyteczność, jak powiedzieć prostemu użytkownikowi, co się właśnie wydarzyło i jak rozwiązać ten problem?
Pathros
38

Dzieje się tak, ponieważ formularz wymaga csrf. W wersji 5.7 zmienili go na @csrf

<form action="" method="post">
    @csrf
    ...

Odniesienie: https://laravel.com/docs/5.7/csrf

David
źródło
6
Jego formularz zawiera token csrf. Nie jestem pewien, czy edytował go później, czy nie.
eResourcesInc
tak, jego forma pierwotnie miała csrfpole, właśnie przejrzałem historię edycji
Dexter Bengil,
13

przypadek 1: jeśli uruchamiasz projekt w systemie lokalnym, np. 127.0.01: 8000,

następnie

dodaj SESSION_DOMAIN=swój plik .env

lub w twoim config / session.php 'domain' => env('SESSION_DOMAIN', ''),

a potem biegnij php artisan cache:clear

przypadek 2: jeśli projekt jest uruchomiony na serwerze i masz domenę taką jak „moja_domena.com”

dodaj SESSION_DOMAIN=mydomain.comswój plik .env

lub w twoim config / session.php 'domain' => env('SESSION_DOMAIN', 'mydomain.com'),

a potem biegnij php artisan cache:clear

Saurabh Mistry
źródło
9

Co powiesz na używanie

{{ csrf_field() }} zamiast @csrf

Błąd 419 jest spowodowany głównie problemami z tokenem CSRF.

Bonish Koirala
źródło
Masz na myśli {{ csrf_field() }}?
Travis Britz
9

Używam Laravel 5.7 miałem ten sam problem a to dlatego, że token csrf nie był w formularzu, więc dodając

@csrf

naprawiono problem

Karim Samir
źródło
7

Spróbuj wypowiedzieć się \App\Http\Middleware\EncryptCookies::classw \app\Http\Kernel.php Mam podobny problem i rozwiązać go w ten sposób. Zapewne nie najlepsze rozwiązanie bo zabezpieczenia ale przynajmniej zadziałało.

Wcześniej próbowałem:

  • Wyczyść pamięć podręczną
  • Wygeneruj nowy klucz aplikacji
  • Uruchom moją aplikację w różnych przeglądarkach (Chrome 70, Mozilla Firefox 57 i IE 11)
  • Uruchom moją aplikację na innym komputerze
  • Skomentuj \App\Http\Middleware\VerifyCsrfToken::classw\app\Http\Kernel.php
  • Skomentuj \Illuminate\Session\Middleware\AuthenticateSession::classw\app\Http\Kernel.php
  • Uaktualnij i obniż Laravel (między 5,6 a 5,7)

Ale żaden z powyższych nie działał dla mnie.

EDYTOWAĆ

Mój przypadek jest taki, że przy każdym logowaniu zostanie utworzony nowy plik sesji (stary nadal istnieje, ale nagle zapomniany. Sprawdź storage/framework/sessions) i generowany jest nowy token CSRF. Więc problem nie dotyczy VerifyCsrfToken.

Jak @Vladd wspomniał w sekcji komentarzy, nigdy nie powinieneś komentować \App\Http\Middleware\VerifyCsrfToken::class. Musisz sprawdzić, czy wysłałeś odpowiedni ŻETON CSRF na serwer.

Prasna Lukito
źródło
1
Spośród tych sposobów, o których wspomniałeś, działało tylko komentowanie \ App \ Http \ Middleware \ VerifyCsrfToken :: class w \ app \ Http \ Kernel.php.
Lex Soft
1
Wyczyść pamięć podręczną, wygeneruj nowy klucz aplikacji + Usuń pliki cookie
wygeneruj dobs
Nigdy nie należy c0mmenting out \ App \ Http \ Middleware \ VerifyCsrfToken :: class. Dlaczego chcesz to zrobić? Aby stworzyć swój własny słaby punkt w aplikacji?
Vladd
@dobs Dzięki za dodanie „+ Usuń pliki cookie”, ponieważ otrzymywałem błąd 419, nawet po zrobieniu wszystkiego, co mogłem, i działało tylko wtedy, gdy wyczyściłem pliki cookie przeglądarki / próbowałem w trybie incognito.
Niraj Pandey
6

zmień swój @csrfplik w welcome.blade.php na<input type="hidden" name="_token" value="{{ csrf_token() }}">

więc twój kod w ten sposób:

<form method="POST" action="/foo" >
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
    <input type="text" name="name"/><br/>
    <input type="submit" value="Add"/>

   <button type="submit">Submit</button>
</form>
Aghnat Atqiya
źródło
6

To może być problem z twoją sesją. Po zabawie z tymi ustawieniami rozwiązałem problem. Dla mnie to ostatnia opcja.

  • Jeśli używasz „pliku” jako sterownika sesji, zajrzyj do pamięci / struktury / sesji, jeśli sesje są zapisywane po odświeżeniu. Jeśli nie, najprawdopodobniej jest to spowodowane nieprawidłowymi uprawnieniami do folderu. Sprawdź, czy Twój magazyn / folder ma odpowiednie uprawnienia
  • Spróbuj wyłączyć cały Javascript na swoich stronach (wyłączając go za pomocą nawigatora lub wewnątrz kodu) i upewnij się, że „http_only” => true,
  • Spróbuj użyć zi bez protokołu HTTPS
  • Upewnij się, że zmienna SESSION_DRIVER NIE jest pusta
  • Spróbuj przełączać się między „encrypt” => false i „encrypt” => true,
  • Spróbuj zmienić nazwę pliku cookie 'cookie' => 'laravelsession',
  • Spróbuj ustawić SESSION_DOMAIN na swoją rzeczywistą domenę LUB zerową
  • Spróbuj przełączać się między 'secure' => env ('SESSION_SECURE_COOKIE', false) i 'secure' => env ('SESSION_SECURE_COOKIE', true),

Źródło: Laravel Session zawsze zmienia każde odświeżenie / żądanie w Laravel 5.4

Bram Janssen
źródło
Tak, po wypróbowaniu wielu innych rzeczy SESSION_SECURE_COOKIEprzełącznik (zmienił go na false) zrobił to za mnie. (wł. localhost:8000)
Marten Koetsier
SESSION_SECURE_COOKIE też był dla mnie problemem, zmieniłem go, postępując zgodnie z przewodnikiem po optymalizacji strony.
Bram Janssen
dla mnie działa z https, ale nie z http ... jakiś pomysł dlaczego? dzięki za świetną odpowiedź, znalezienie jej zajęło mi godziny.
sharkyenergy
4

dodaj token csrf, a Twój problem zostanie rozwiązany. {{csrf_token}} lub @csrf

samair ali
źródło
4

Aby rozwiązać ten błąd, musisz najpierw wstawić jedno z następujących poleceń do znacznika formularza.

@csrf LUB {{ csrf_field }}

Jeśli problem nie został rozwiązany, wykonaj następujące czynności: (Zauważ, że jedno z powyższych poleceń musi znajdować się w tagu formularza)

1. wstaw jedno z następujących poleceń do znacznika formularza @csrfLUB{{ csrf_field }}

2. Otwórz plik .env i zmień wartości na „plik” w sekcji SESSION_DRIVER.

3.Następnie zresetuj pamięć podręczną Laravel. wpisz poniższe polecenia w terminalu

php artisan view:clear php artisan route:clear php artisan cache:clear

php artisan config:cache

4. Na ostatnim etapie odłącz projekt od serwisu i ponownie kliknij serwis php artisan

Mam nadzieję, że problem został rozwiązany

Hosein azimi
źródło
3

Po tak długim czasie udało mi się to rozwiązać w ten sposób

Moja ścieżka instalacyjna laravel nie była taka sama, jak ustawiona w pliku konfiguracyjnym session.php

'domain' => env('SESSION_DOMAIN', 'example.com'),
ismail bangee
źródło
2

To może być przesada, ale możesz spróbować tego:

// Wywołanie formularza o nazwie route z dodanym ukrytym polem tokena.

<form method="POST" action="{{ route('foo') }}" >
    @csrf
    <input type="hidden" name="_token" value="{!! csrf_token() !!}">
    <input type="text" name="name"/><br/>
    <input type="submit" value="Add"/>
</form>

// Nazwana trasa

Route::post('/foo', function () {
    return 'bar';
})->name('foo');

// Dodaj to w <head></head>bloku:

<meta name="_token" content="{!! csrf_token() !!}" />

Przetestowałem to na moim lokalnym komputerze przy użyciu Homestead na Laravel 5.7, który był świeżą instalacją przy użyciu Laravel Installer 2.0.1 i zadziałało. Jakie jest Twoje środowisko?

Teoria: Zastanawiam się, czy ma to coś wspólnego z renderowaniem tagów html przez blade z {{ }}vs. {!! !!}w twoim środowisku lub jak to serwujesz (np. php artisan serve). Co sprawia, że myślę, że jest line 335wśród /vendor/laravel/framework/src/illuminate/Foundation/helpers.phppowinno uczynić tę samą linię ręcznie wpisany powyżej.

jeremykenedy
źródło
Tak fajnie, ale <meta>tagi powinny być umieszczane wewnątrz <head>, a nie wewnątrz <body>. Nie jestem pewien, czy walidator HTML chciałby tego.
emix
Powiedziałbym, że masz rację i to powinno zostać przeniesione do głowy.
jeremykenedy
2

W kodzie nie ma problemu. Sprawdziłem tym samym kodem, który napisałeś przy nowej instalacji.

Kod formularza:

<form method="POST" action="/foo" >
    @csrf
    <input type="text" name="name"/><br/>
    <input type="submit" value="Add"/>
</form>

web.php kod pliku:

Route::get('/', function () {
    return view('welcome');
});

Route::post('/foo', function () {
    echo 1;
    return;
});

Wynik po przesłaniu formularza to: Wyjście po przesłaniu formularza

Jeśli wyczyścisz pamięć podręczną przeglądarki lub spróbujesz z inną przeglądarką, myślę, że zostanie to naprawione.

engrhussainahmad
źródło
2

Szybkim złym podejściem jest przejście do app \ http \ middleware \ verifycsrftoken.php i dodanie trasy w $ except list. Żądanie pocztowe będzie ignorowane przy weryfikacji tokena CSRF.

protected $except = [
    //
    'doLogin.aspx',
    'create_coupon',
];
Qasim Ali
źródło
2

419 | strona ten błąd oznacza problem z zabezpieczeniami laravel oznacza to, że pole tokena csrf nie jest używane poprawnie.

użyj, {{csrf_field}} a problem zostanie rozwiązany.

Flutterer
źródło
2

Powinno działać, jeśli wypróbujesz wszystkie te kroki:

  1. Upewnij się, że Twoja sesja jest dobrze skonfigurowana. Najłatwiejszym sposobem jest utworzenie pliku i upewnienie się, że folder przechowywania ma uprawnienia chmod 755, a następnie w .envustawieniach jak poniżej, najłatwiejszym sposobem ustawienia jest sterownik sesji plików.

    SESSION_DRIVER=file
    SESSION_DOMAIN=
    SESSION_SECURE_COOKIE=false
    
  2. Upewnij się, że folder pamięci podręcznej jest wyczyszczony i można go zapisać, możesz to zrobić, uruchamiając poniższe polecenie artisan.

    php artisan cache:clear
    
  3. Upewnij się, że uprawnienia do folderów są dobrze ustawione, powinny być skonfigurowane jak poniżej:

    sudo chmod -R 755 storage
    sudo chmod -R 755 vendor
    sudo chmod -R 644 bootstrap/cache
    
  4. Upewnij się, że formularz zawiera @csrftoken.

Mam nadzieję, że to rozwiąże Twój problem.

Kamaro Lambert
źródło
1

W Twoim Http/Kernel.php

spróbuj skomentować tę linię:

\Illuminate\Session\Middleware\AuthenticateSession::class,

w sieciowym oprogramowaniu pośrednim

to może być źródłem Twojego problemu

Mathieu Ferre
źródło
1

Domyślnie nie miałem tego problemu. Więc zrobiłem chmod -R 644 sessions powtórzenie problemu.

wprowadź opis obrazu tutaj

Następnie nadałem uprawnienia do folderu sesji wg chmod -R 755 sessions

teraz mój kod projektu znów działa.

wprowadź opis obrazu tutaj

Przyczyną tego jest to, że przechowujesz pamięć podręczną w pliku bez uprawnień do zapisu.

Plik konfiguracyjny sesji jest przechowywany w config / session.php. Pamiętaj, aby przejrzeć opcje dostępne w tym pliku. Domyślnie Laravel jest skonfigurowany do używania sterownika sesji plików, który będzie dobrze działał w wielu aplikacjach. W aplikacjach produkcyjnych możesz rozważyć użycie sterowników memcached lub redis w celu jeszcze szybszego działania sesji.

Rozwiązania:

1 - Jak naprawiłem powyżej, możesz nadać 755 uprawnienia do folderu sesji. 2 - Możesz użyć innej konfiguracji sterownika sesji.

plik - sesje są przechowywane w pamięci / strukturze / sesjach. cookie - sesje przechowywane są w bezpiecznych, zaszyfrowanych plikach cookie. baza danych - sesje są przechowywane w relacyjnej bazie danych. memcached / redis - sesje są przechowywane w jednym z tych szybkich sklepów opartych na pamięci podręcznej. tablica - sesje są przechowywane w tablicy PHP i nie będą utrwalane.

Miej na uwadze; Jeśli chcesz używać memcached / redis, musisz mieć je zainstalowane na serwerze lub Twój kontener docker redis musi być uruchomiony.

Anar Bayramov
źródło
1

W rzeczywistości CSRF jest tokenem opartym na sesji. Dodaj trasę do grupy tras i dodaj oprogramowanie pośredniczące, które kontroluje sesje.

web jest domyślnym oprogramowaniem pośredniczącym w programie laravel i może kontrolować żądania sesji.

Route::group(array('middleware' => ['web']), function () {
  Route::post('/foo', function () {
     echo 1;
     return;
  });
});
Zia
źródło
1

Jeśli masz już dyrektywę csrf , być może zmieniłeś sposób działania sesji.

W config/session.phpsprawdzić „bezpieczny” pole. Powinna mieć wartość false, jeśli protokół https nie jest dostępny na Twoim serwerze.

Możesz również umieścić SESSION_SECURE_COOKIE=FALSEswój .envplik (katalog główny).

Ręcznik
źródło
1

otwórz wiersz poleceń cmd w swoim projekcie.

1. polecenie

php artisan config:cache

2. komenda

php artisan route:clear
Biblbroks42
źródło
1

Czy masz również csrf w nagłówku swojej aplikacji?

<meta name="csrf-token" content="{{ csrf_token() }}">
iranimij
źródło
1

Chociaż formularz ma @csrf, nadal jest widoczny419 pages has expired

Rozwiązałem to po aktualizacji SESSION_SECURE_COOKIEna false w config / session.php

'secure' => env('SESSION_SECURE_COOKIE', false)

niż wyczyść pamięć podręczną

Kakada Neang
źródło
1

Przejdź do config / session.php

znajdź wiersz

'secure' => env('SESSION_SECURE_COOKIE', true),

zmień to na fałsz

'secure' => env('SESSION_SECURE_COOKIE', false),

Jeśli ten parametr jest ustawiony na TRUE, przeglądarka będzie wymagać użycia protokołu HTTPS, w przeciwnym razie nie zapisze sesji. Ponieważ to nie jest ważne

Rafayel
źródło
1

Po prostu przeszedłem przez to i zatrzymałem się tutaj, aby uzyskać odpowiedź. W moim przypadku rozwiązaniem było wyczyszczenie historii przeglądarki.

Isma'el
źródło
1

W moim przypadku?> Na końcu route.php. Spędziłem tam dużo czasu ...

Juan Angel
źródło
to samo, zapomniałem dodać ?>do końcaweb.php
msalihbindak
0

Po prostu miałem dokładnie ten sam problem i sprowadziłem się do tego, że byłem całkowicie głupi. Wyłączyłem wszystkie pola formularza (a nie tylko przycisk przesyłania) za pomocą javascript przed wysłaniem tego formularza! To oczywiście spowodowało, że wszystkie elementy formularza nie zostały przesłane (w tym ukryte _tokenpole), co z kolei spowodowało błąd 419!

Mam nadzieję, że to pomoże komuś po kilku godzinach drapania się po głowie!

Wyłączone dane wejściowe formularza nie pojawiają się w żądaniu

Bazgrać
źródło
0

Dostałem ten numer dawno temu. Przypomniałem sobie, że powoduje to pozwolenie storage/framework/sessions. Możesz chcieć to zmienić za pomocą chmod -R 0777 storage/framework/sessionspolecenia. U mnie to zadziałało.

Duy Nguyen
źródło
0

W moim przypadku jest to bardzo śmieszne. Otrzymuję błąd 419, kiedy umieszczam Auth::routes()na górze pliku trasy.

Auth::routes();

Route::middleware('auth')->group(function () {
    Route::get('/', 'DashboardController@index')->name('dashboard');
});

Naprawiłem błąd, przechodząc Auth::routes();do dolnej części pliku trasy.

Route::middleware('auth')->group(function () {
    Route::get('/', 'DashboardController@index')->name('dashboard');
});

Auth::routes();

Może pomoże to również w twojej sprawie. Powodzenia.

Lyhong
źródło
0

Zwróć uwagę, że pojawia się błąd 419, jeśli próbujesz przesłać duży plik, który przekracza limit rozmiaru pliku post. W takim przypadku możesz zwiększyć zarówno upload_max_filesize, jak i post_max_size do rozsądnej kwoty (np. 10 mln lub 20 mln zależy od twojego przypadku użycia i zasobów), sprawdź tutaj: https://stackoverflow.com/a/2184541/2100489

Może to jednak powodować problemy ze zużyciem zasobów, np. Przepustowością i pamięcią masową. Jako rozwiązanie możesz sprawdzić rozmiar pliku przed wysłaniem formularza i wyświetlić ostrzeżenie.

Kiafar
źródło