2017-04-13 1 views
9

Meine App verwendet Reagieren auf das Frontend und Laravel 5.4 auf dem Back-End. Ich verwende fetch(), um Daten vom Backend anzufordern. Das Problem besteht darin, dass beim Laden der Seite zwei Sitzungen erstellt werden. A TokenMismatchException wird von der CSRF-Middleware ausgelöst, wenn eine Anforderung POST gestellt wird, da das Token, das gesendet wird, mit der ersten Sitzung übereinstimmt, die erstellt wird, aber es gegen die Sekunde überprüft.React Fetch zu Laravel API erstellt neue Sitzung

Ich gründe das Token in app.blade.php

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

Und das Token in der Config holen

fetchConfig = { 
    headers: { 
     'Content-Type': 'application/json', 
     'Accept': 'application/json', 
     'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') 
    }, 
    credentials: 'same-origin' 
}} 

Hier sind die entschlüsselten Sitzungen greifen:

a:3:{s:6:"_token";s:40:"7obvOzPaqqJDtVdij8RaqrvmTFLjKA2qnvYMxry6";s:9:"_previous";a:1:{s:3:"url";s:24:"http://localhost/page";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}} 

a:3:{s:6:"_token";s:40:"5Aiws9Qy72YzlkfWX81zkhzrSeiMDYjFWiLeDAwN";s:9:"_previous";a:1:{s:3:"url";s:41:"http://localhost/api/page";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}} 

anfordern URL: http://localhost/page

API URL: http://localhost/api/page

Wie kann ich eine neue Sitzung verhindern, erstellt wird, wenn die App GET Anfrage seine anfängliche Reaktion macht?

+0

Welche Session-Treiber verwenden Sie? –

+0

Ich benutze den 'Datei'-Session-Treiber. – bill

+0

Wenn Sie das JWT Auth-Token (JSON Web Token Authentication) für die Laravel-API verwendet haben. weil die API den Status nicht beibehalten kann.Wenn Sie also eine Csrf-Token-Verifizierung benötigen, müssen Sie sie als privaten Anspruch in einem Meta-Tag oder in einer JWT-Nutzlast speichern. –

Antwort

9

Laravel generiert automatisch eine CSRF "Token" für jede aktive Benutzersitzung von der Anwendung verwaltet. Mit diesem Token wird überprüft, ob der authentifizierte Benutzer derjenige ist, der die Anforderungen tatsächlich an die Anwendung sendet. : https://laravel.com/docs/5.4/csrf

APIs sind zustandslos. Es gibt nichts wie session in APIs. Daher sollten Sie das CSRF-Token nicht in der API verwenden. Wenn Sie Kernel.php von Laravel überprüfen. Sie werden sehen, dass Tylor keine VerifyCsrf Middleware in der API-Gruppe hinzugefügt hat. Dies legt nahe, dass CSRF nur in der Anfrage verwendet wird, die eine Sitzung hat, d. H. Eine Stateful-Anfrage. Ich würde Ihnen empfehlen, das JWT-basierte Authentifizierungssystem für API zu verwenden. Für mehr über JWT check here.

Sie können diese Laravel Paket für JWT verwenden: https://github.com/tymondesigns/jwt-auth

5

Ich bin mir nicht sicher, was ist Ihre Anfrage URL und was ist Ihre Ziel-API-URL. Stellen Sie sicher, dass beide in derselben Domäne (einschließlich Subdomäne) sind.

Ich denke, es ist eine gute Idee CSRF Validierung deaktivieren nur für die API-Routen wie diese könnten von anderen Domänen, native Anwendungen usw.

Sie tun können verwendet werden, die durch folgende Klassendatei hinzufügen: app/Http/Middleware/VerifyCsrfToken.php

<?php 

namespace App\Http\Middleware; 

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; 

class VerifyCsrfToken extends BaseVerifier 
{ 
    /** 
    * The URIs that should be excluded from CSRF verification. 
    * 
    * @var array 
    */ 
    protected $except = [ 
     'api/*', 
    ]; 
} 

Stellen Sie sicher, Kernal.php zu bearbeiten, um die neue Klasse Punkt:

protected $middleware = [ 
    'csrf' => 'App\Http\Middleware\VerifyCsrfToken' 
]; 

um mehr zu erfahren, wie Laravel uns es CSRF überprüfen this laracast video

+0

Vielen Dank für die Antwort! Ich fügte der Frage die Anfrage- und API-URLs hinzu, da sie in den Sitzungsdaten versteckt waren. Ihre Lösung funktioniert, um die csrf-Middleware zu umgehen, aber mehrere Sitzungen werden noch erstellt. Ich würde das gerne nach Möglichkeit beheben. – bill

Verwandte Themen