Richiesta di post in Laravel - Errore - 419 Spiacenti, la tua sessione / 419 la tua pagina è scaduta


90

Ho installato Laravel 5.7

Aggiunto un modulo al file \resources\views\welcome.blade.php

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

Aggiunto al file \routes\web.php

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

Dopo aver inviato una richiesta POST:

419 Spiacenti, la tua sessione è scaduta. Aggiorna e riprova.

Nella versione 5.6non c'era un problema del genere.


Hai provato ad aggiungere un reindirizzamento? Invece di return;te puoi chiamare return redirect()->back();. Da quello che posso vedere, l'app non ha nulla a che fare dopo la richiesta del post. Forse puoi reindirizzarlo a una vista dopo aver elaborato la richiesta.
dcangulo

1
Ho lo stesso problema. Quando passo alla sessione del database, ciò accade e quando torno a filefor SESSION_DRIVERin .envfunziona bene. Perché la sessione basata sul database non funziona.
Junaid Qadir Shekhanzai

Ho copiato il tuo codice esatto in una nuova installazione di laravel 5.7. Ha funzionato. C'è un problema altrove.
Kyle Wardle

questo problema a causa del problema del token. Ho provato a eseguire lo stesso codice in questo modo, ma non ho ricevuto alcun errore. Dovresti fornire più informazioni come il tuo driver di sessione, visualizzazione del valore _token nel modulo. Inoltre, puoi eseguire il debug in questa vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.phpriga di file 67 per sapere perché
bangnokia

1
Mi sono reso conto che avevo usato il sessionstavolo per uno scopo diverso. Dopo aver modificato il nome di questa tabella in uno più adatto e aver eseguito artisan session:tablee aggiornato la migrazione, tutto funziona
correttamente

Risposte:


123

Prima di leggere di seguito assicurati di avere @csrfo {{ csrf_field() }}nella tua forma come

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

Viene visualizzato il messaggio di errore Sessione scaduta o 419 Pagina scaduta in larvel perché da qualche parte la verifica del token csrf non riesce, il che significa che il App\Http\Middleware\VerifyCsrfToken::classmiddleware è già attivato. Nella forma @csrfè già stata aggiunta la direttiva blade, il che dovrebbe andare bene.

Quindi l'altra area da controllare è la sessione. La csrfverifica del token è direttamente coinvolta nella tua sessione, quindi potresti voler controllare se il tuo driver di sessione funziona o meno, ad esempio un Redis configurato in modo errato potrebbe causare un problema.

Forse puoi provare a cambiare il tuo driver / software di sessione dal tuo .envfile, i driver supportati sono forniti di seguito

Driver di sessione supportati in Laravel 5, Laravel 6 e Laravel 7 (Doc Link)

  • file - le sessioni vengono archiviate in storage / framework / sessioni.
  • cookie - le sessioni vengono memorizzate in cookie protetti e crittografati.
  • database - le sessioni sono archiviate in un database relazionale.
  • memcached/ redis- le sessioni sono archiviate in uno di questi veloci archivi basati sulla cache.
  • array - le sessioni vengono memorizzate in un array PHP e non verranno mantenute.

Se il tuo modulo funziona dopo aver cambiato il driver della sessione, allora c'è qualcosa di sbagliato in quel particolare driver, prova a correggere l'errore da lì.

Possibili scenari soggetti a errori

  • Probabilmente le sessioni basate su file potrebbero non funzionare a causa dei problemi di autorizzazione con la /storagedirectory (una rapida ricerca su Google ti porterà la soluzione), ricorda inoltre che mettere 777 per la directory non è mai la soluzione.

  • Nel caso del driver del database, la connessione al database potrebbe essere errata o la sessionstabella potrebbe non esistere o configurata in modo errato (la parte di configurazione errata è stata confermata come un problema secondo il commento di @Junaid Qadir).

  • redis/memcached la configurazione è errata o viene manipolata contemporaneamente da qualche altra parte di codice nel sistema.

Potrebbe essere una buona idea eseguire php artisan key:generatee generare una nuova chiave dell'app che, a sua volta, svuoterà i dati della sessione.

Cancella la cache del browser HARD , ho scoperto che Chrome e Firefox sono i colpevoli più di quanto possa ricordare.

Ulteriori informazioni sul motivo per cui le chiavi dell'applicazione sono importanti


1
A volte è solo che i browser, principalmente Chrome, non inseriscono il valore della sessione Set-Cookie perché è malformato o non standard. Quindi Laravel non troverà alcun valore di sessione esistente dalla richiesta HTTP da confrontare con il _tokenvalore ricevuto dal FORM. Evita di utilizzare SESSION_DOMAIN=...con IP che Chrome e le specifiche dei cookie HTTP considerano non sicuri.
KeitelDOG

Ho lo stesso problema, ma non ricevo l'errore costantemente. Succede solo di tanto in tanto. Immagino che ciò significhi che non ci sono problemi con il driver di sessione, perché funziona il 99% delle volte. Ma sto eseguendo un'app live e ricevo lamentele dai clienti di tanto in tanto. Tuttavia è molto raro. Sto usando il driver della sessione di file. Qualcuno sa perché questo accade nel mio caso? Grazie
TheAngelM97

@ TheAngelM97 È possibile riprodurre facilmente questo errore accedendo alla pagina di accesso o di registrazione. Non fare niente per forse più di 30 minuti. Quindi, quando fai clic su Invia, viene 419 Page Expiredvisualizzato. Per motivi di usabilità, come si fa a dire a un semplice utente cosa è appena successo e come risolverlo?
Pathros

38

Questo perché il modulo richiede un csrf. Nella versione 5.7, lo hanno cambiato in @csrf

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

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


6
Il suo modulo include un token CSRF. Non sono sicuro se l'ha modificato in seguito o meno.
eResourcesInc

sì, il suo modulo originariamente ha un csrfcampo, ho appena esaminato la cronologia delle modifiche
Dexter Bengil

Questo non risolve il problema anche nel mio caso, dato che ce l'ho sempre nella mia forma, ma ho iniziato ad affrontare errori a causa di altri cambiamenti
Sami

14

caso 1: se stai eseguendo un progetto nel tuo sistema locale come 127.0.01: 8000,

poi

aggiungi SESSION_DOMAIN=nel tuo file .env

o nel tuo config / session.php 'domain' => env('SESSION_DOMAIN', ''),

e poi corri php artisan cache:clear

caso 2: se il progetto è in esecuzione sul server e hai un dominio come "miodominio.com"

aggiungi SESSION_DOMAIN=mydomain.comnel tuo file .env

o nel tuo config / session.php 'domain' => env('SESSION_DOMAIN', 'mydomain.com'),

e poi corri php artisan cache:clear


9

Che ne dici di usare

{{ csrf_field() }} invece di @csrf

L'errore 419 è principalmente dovuto a problemi con il token CSRF.


Intendi {{ csrf_field() }}?
Travis Britz

Genera lo stesso html di @csrf, quindi lo stesso risultato
Sami

9

Uso Laravel 5.7 ho avuto lo stesso problema ed era perché il token csrf non era nel modulo, quindi aggiungendo

@csrf

risolto il problema


8

Prova a commentare \App\Http\Middleware\EncryptCookies::classin \app\Http\Kernel.php Ho un problema simile e l'ho risolto in questo modo. Probabilmente non è la soluzione migliore perché la sicurezza, ma almeno ha funzionato.

In precedenza ho provato:

  • Cancella cache
  • Genera una nuova chiave dell'app
  • Esegui la mia app in vari browser (Chrome 70, Mozilla Firefox 57 e IE 11)
  • Esegui la mia app su un altro computer
  • Commenta \App\Http\Middleware\VerifyCsrfToken::classin\app\Http\Kernel.php
  • Commenta \Illuminate\Session\Middleware\AuthenticateSession::classin\app\Http\Kernel.php
  • Upgrade e downgrade di Laravel (tra 5.6 e 5.7)

Ma nessuno di questi ha funzionato per me.

MODIFICARE

Il mio caso qui è che ogni volta che effettuo il login, verrà creato un nuovo file di sessione (quello vecchio è ancora persistente, ma improvvisamente dimenticato. Controllare storage/framework/sessions) e viene generato un nuovo token CSRF. Quindi il problema non è con VerifyCsrfToken.

Come menzionato da @Vladd nella sezione commenti, non dovresti mai commentare \App\Http\Middleware\VerifyCsrfToken::class. Devi controllare di aver inviato il TOKEN CSRF corretto al server.


1
Tra i modi che hai menzionato, solo commentare \ App \ Http \ Middleware \ VerifyCsrfToken :: class in \ app \ Http \ Kernel.php ha funzionato per me.
Lex Soft

1
Svuota la cache, genera una nuova chiave dell'app + Rimuovi i cookie
dobs

Non dovrai mai c0mmentare \ App \ Http \ Middleware \ VerifyCsrfToken :: class. Perché dovresti farlo? Per creare il tuo punto debole nell'app?
Vladd

@dobs Grazie per aver aggiunto "+ Rimuovi cookie" perché ho ricevuto un errore 419 anche dopo aver fatto tutto ciò che potevo e ha funzionato solo quando ho cancellato i cookie del browser / provato in incognito.
Niraj Pandey

6

cambia il tuo @csrfin welcome.blade.php in<input type="hidden" name="_token" value="{{ csrf_token() }}">

quindi il tuo codice in questo modo:

<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>

6

Potrebbe essere un problema con la tua sessione. Dopo aver giocato con queste impostazioni ho risolto il mio problema. Per me si è rivelata l'ultima opzione.

  • Se stai usando "file" come driver di sessione, controlla in memoria / framework / sessioni se le sessioni vengono salvate dopo un aggiornamento. In caso contrario, molto probabilmente è dovuto a autorizzazioni di cartella errate. Verifica che il tuo archivio / cartella abbia il diritto corretto
  • Prova a disabilitare tutto il Javascript nelle tue pagine (disabilitandolo tramite navigatore o all'interno del codice) e assicurati che 'http_only' => true,
  • Prova a utilizzare con e senza https
  • Assicurati che la variabile SESSION_DRIVER NON sia nulla
  • Prova a passare da 'encrypt' => false e 'encrypt' => true,
  • Prova a cambiare il nome del cookie "cookie" => "laravelsession",
  • Prova a impostare SESSION_DOMAIN sul tuo dominio effettivo OPPURE null
  • Prova a passare da 'secure' => env ('SESSION_SECURE_COOKIE', false) e 'secure' => env ('SESSION_SECURE_COOKIE', true),

Fonte: Laravel Session cambia sempre ogni aggiornamento / richiesta in Laravel 5.4


Sì, dopo aver provato molte altre cose, l' SESSION_SECURE_COOKIEinterruttore (cambiato in false) l'ha fatto per me. (on localhost:8000)
Marten Koetsier

SESSION_SECURE_COOKIE è stato anche il problema per me, l'ho cambiato seguendo una guida per l'ottimizzazione del sito web.
Bram Janssen

per me funziona con https ma non con http ... qualche idea perche? grazie per l'ottima risposta, mi ci sono volute ore per trovarla.
sharkyenergy

5

Per risolvere questo errore devi prima inserire uno dei seguenti comandi nel tag del form.

@csrf O {{ csrf_field }}

Se il tuo problema non viene risolto, procedi come segue: (Nota che uno dei comandi sopra deve essere nel tag del modulo)

1.Inserire uno dei seguenti comandi nel tag del modulo @csrfOR{{ csrf_field }}

2.Aprire il file .env e modificare i valori in "file" nella sezione SESSION_DRIVER.

3.Quindi dovresti resettare la cache di laravel. digitare sotto i comandi nel terminale

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

php artisan config:cache

4.Nel passaggio finale, scollegare il progetto dal servizio e fare nuovamente clic su php artisan serve

Spero che il tuo problema sia risolto


4

aggiungi il token csrf e il tuo problema sarà risolto. {{csrf_token}} o @csrf


3

Dopo così tanto tempo ho risolto in questo modo

Il mio percorso di installazione di laravel non era lo stesso impostato nel file di configurazione session.php

'domain' => env('SESSION_DOMAIN', 'example.com'),

2

Potrebbe essere eccessivo ma puoi provare questo:

// Modulo che chiama route denominata con campo token nascosto aggiunto.

<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>

// Percorso denominato

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

// Aggiungi questo all'interno del <head></head>blocco:

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

L'ho testato sul mio locale usando Homestead su Laravel 5.7 che era una nuova installazione usando Laravel Installer 2.0.1 e ha funzionato. Qual è il tuo ambiente?

Teoria: mi chiedo se questo abbia qualcosa a che fare con il rendering di blade tag html con {{ }}vs. {!! !!}sul tuo ambiente o come lo stai servendo (ad es. php artisan serve). Quello che mi fa pensare che è line 335di /vendor/laravel/framework/src/illuminate/Foundation/helpers.phpdovrebbe rendere la stessa linea digitato manualmente in precedenza.


Sì, fantastico, ma i <meta>tag dovrebbero essere inseriti all'interno del file <head>, non all'interno del file <body>. Non sono sicuro che al validatore HTML piacerebbe questo.
emix

Direi che hai ragione e che dovrebbe essere spostato in testa.
jeremykenedy

2

Non ci sono problemi nel codice. Ho controllato con lo stesso codice che hai scritto con la nuova installazione.

Codice modulo:

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

web.php codice file:

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

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

Il risultato dopo aver inviato il modulo è: Output dopo aver inviato il modulo

Se svuoti la cache del browser o provi con un altro browser, penso che verrà risolto.


2

Un rapido approccio sbagliato è quello di andare su app \ http \ middleware \ verifycsrftoken.php e aggiungere il percorso in $ tranne l'elenco. La richiesta di post verrà ignorata per la verifica del token CSRF.

protected $except = [
    //
    'doLogin.aspx',
    'create_coupon',
];

2

419 | pagina questo errore indica un problema di sicurezza di laravel significa che il campo token csrf non è utilizzato correttamente.

utilizzare {{csrf_field}} e il problema verrà risolto.


2

Dovrebbe funzionare se provi tutti questi passaggi:

  1. Assicurati che la tua sessione sia ben configurata, il modo più semplice è renderlo file e assicurarti che la cartella di archiviazione abbia l'autorizzazione chmod 755, quindi nel tuo lo .envhai impostato come sotto, il driver di sessione del file è il modo più semplice per impostare.

    SESSION_DRIVER=file
    SESSION_DOMAIN=
    SESSION_SECURE_COOKIE=false
    
  2. Assicurati che la cartella Cache sia cancellata e scrivibile, puoi farlo eseguendo sotto il comando artisan.

    php artisan cache:clear
    
  3. Assicurati che le autorizzazioni della cartella siano ben impostate, dovrebbero essere configurate come di seguito:

    sudo chmod -R 755 storage
    sudo chmod -R 755 vendor
    sudo chmod -R 644 bootstrap/cache
    
  4. Assicurati che il tuo modulo abbia il @csrftoken incluso.

Spero che questo risolva il tuo problema.


l'impostazione sudo delle autorizzazioni ha bloccato completamente il mio laravel.
Vladimir Despotovic

2

Vai a config / sessions.php

trova la riga

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

cambiarlo in falso

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

Se questo parametro è impostato su TRUE, il browser richiederà di utilizzare il protocollo HTTPS, altrimenti non memorizzerà la sessione. Poiché non è valido


1

Nel tuo Http/Kernel.php

prova a commentare questa riga:

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

nel tuo array middleware web

potrebbe essere la radice del tuo problema


1

Di default non ho avuto questo problema. Quindi quello che ho fatto è chmod -R 644 sessions replicare il problema.

inserisci qui la descrizione dell'immagine

Successivamente ho dato i permessi alla cartella delle sessioni di chmod -R 755 sessions

ora il codice del mio progetto funziona di nuovo.

inserisci qui la descrizione dell'immagine

Il motivo per cui accade è che archivi la cache su file senza i permessi di scrittura.

Il file di configurazione della sessione è memorizzato in config / session.php. Assicurati di rivedere le opzioni disponibili in questo file. Per impostazione predefinita, Laravel è configurato per utilizzare il driver di sessione file, che funzionerà bene per molte applicazioni. Nelle applicazioni di produzione, potresti prendere in considerazione l'utilizzo dei driver memcached o redis per prestazioni di sessione ancora più veloci.

Soluzioni:

1 - Come ho corretto sopra, puoi dare l'autorizzazione 755 alla cartella delle sessioni. 2 - È possibile utilizzare un'altra configurazione del driver di sessione.

file: le sessioni vengono archiviate in archivio / framework / sessioni. cookie: le sessioni vengono memorizzate in cookie protetti e crittografati. database: le sessioni vengono archiviate in un database relazionale. memcached / redis - le sessioni sono memorizzate in uno di questi veloci archivi basati su cache. array - le sessioni sono memorizzate in un array PHP e non saranno persistenti.

Tenere presente; Se vuoi usare memcached / redis devi averli installati sul tuo server o il tuo container redis docker deve essere in esecuzione.


1

In realtà CSRF è un token basato sulla sessione. Aggiungi il tuo percorso in un gruppo di percorsi e aggiungi un middleware che controlla le sessioni.

web è un middleware predefinito in laravel e può controllare le richieste di sessione.

Route::group(array('middleware' => ['web']), function () {
  Route::post('/foo', function () {
     echo 1;
     return;
  });
});

1

Se hai già la direttiva csrf , potresti aver cambiato il modo in cui vengono eseguite le sessioni.

In config/session.php, seleziona il campo "protetto" . Dovrebbe essere falso se https non è disponibile sul tuo server.

Puoi anche inserire SESSION_SECURE_COOKIE=FALSEil tuo .envfile (directory principale).


1

apri la riga di comando cmd sul tuo progetto.

1.command

php artisan config:cache

2.com e

php artisan route:clear

1

Hai anche il csrf nell'intestazione della tua domanda?

<meta name="csrf-token" content="{{ csrf_token() }}">

1

Mentre il modulo ha @csrf, si vede ancora419 pages has expired

L'ho risolto dopo l' SESSION_SECURE_COOKIEopzione di aggiornamento su false in config / session.php

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

che svuotare la cache


1

Ho appena esaminato questo argomento e mi fermo qui per una risposta .. Nel mio caso la soluzione era cancellare la cronologia del browser.


1

Nel mio caso c'era un?> Alla fine di routes.php. Ho passato molto tempo lì ...


1
stesso, ho dimenticato di aggiungere ?>alla fine diweb.php
msalihbindak

1
WOW. Non esattamente lo stesso problema nel mio caso, ma la tua soluzione mi ha fatto controllare questo, e quando l'ho fatto, ho notato degli spazi bianchi prima del tag di apertura <?php , ed è questo che causava un 419 su ogni modulo del sito! Stranamente, non è successo con PHP 7.3 ed è iniziato dopo l'aggiornamento a 7.4!
Ben Johnson,

0

Ho appena avuto lo stesso identico problema e ho dovuto essere completamente stupido. Avevo disabilitato tutti i campi del modulo (piuttosto che solo il pulsante di invio) tramite javascript prima di inviare detto modulo! Ciò, ovviamente, ha comportato che tutti gli elementi del modulo non venissero inviati (incluso il _tokencampo nascosto ) che a sua volta ha generato l'errore 419!

Spero che questo aiuti qualcuno da poche ore di grattarsi la testa!

Gli input del modulo disabilitati non vengono visualizzati nella richiesta


0

Ho avuto questo problema molto tempo fa. Mi sono ricordato che causa il permesso di storage/framework/sessions. Potresti volerlo cambiare tramite chmod -R 0777 storage/framework/sessionscomando. Ha funzionato per me.


0

Nel mio caso è molto ridicolo. Ottengo l'errore 419 quando metto Auth::routes()all'inizio del file del percorso.

Auth::routes();

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

E ho corretto l'errore spostandomi Auth::routes();in fondo al file del percorso.

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

Auth::routes();

Forse può aiutare anche il tuo caso. In bocca al lupo.


0

Tieni presente che ricevi l'errore 419 se stai tentando di caricare un file di grandi dimensioni che supera il limite di dimensione del file post. In questo caso puoi aumentare sia upload_max_filesize che post_max_size a un importo ragionevole, (ad esempio 10M o 20M dipende dal tuo caso d'uso e dalle risorse), controlla qui: https://stackoverflow.com/a/2184541/2100489

Ma questo può causare problemi di consumo di risorse, ad esempio larghezza di banda e spazio di archiviazione. Come soluzione puoi controllare la dimensione del file prima di inviare il modulo e mostrare un messaggio di avviso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.