2017-04-13 59 views
9

Moja aplikacja używa React na interfejsie użytkownika i Laravel 5.4 na zapleczu. Używam fetch() do żądania danych z zaplecza. Problem polega na tym, że dwie sesje są tworzone po załadowaniu strony. Wywoływarka TokenMismatchException jest zgłaszana przez oprogramowanie pośredniczące CSRF po otrzymaniu żądania POST, ponieważ wysłany token odpowiada pierwszej utworzonej sesji, ale sprawdza się względem drugiej.React Fetch to Laravel API Tworzy nową sesję

mam ustawienie token w app.blade.php

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

i chwytając token w config zwrcania

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

Oto odszyfrowane sesje:

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:{}}} 

Zapytanie URL: http://localhost/page

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

Jak mogę zapobiec nową sesję z tworzone kiedy React aplikacja sprawia, że ​​jego początkowy GET prośbę?

+0

Który kierowca sesja używasz? –

+0

Używam sterownika 'file' session. – bill

+0

Jeśli użyłeś tokenu JWT Auth (JSON Web Token Authentication) do Laravel API. ponieważ API nie może utrzymać stanu.Tak więc, jeśli potrzebujesz weryfikacji Token Token, musisz zaimplementować ją, przechowując ją w metatagu lub w ładunku JWT jako prywatne roszczenie. –

Odpowiedz

9

laravel automatycznie generuje CSRF „żeton” dla każdej aktywnej sesji użytkownika zarządzany przez aplikację. Ten token służy do sprawdzania, czy uwierzytelniony użytkownik faktycznie wysyła żądania do aplikacji. : https://laravel.com/docs/5.4/csrf

Interfejsy API są bezpaństwowcami. W interfejsach API nie ma nic takiego jak session. Więc nie powinieneś używać tokenu CSRF w API. Jeśli sprawdzisz Kernel.php laravel. Zobaczysz, że Tylor nie dodał oprogramowania pośredniego VerifyCsrf w grupie API. Co sugeruje, że CSRF jest używany tylko w żądaniu sesji, np. Żądanie stanowe. Poleciłbym użyć systemu uwierzytelniania opartego na JWT dla API. Więcej informacji o JWT check here.

Można użyć tego pakietu laravel dla JWT: https://github.com/tymondesigns/jwt-auth

5

Nie jestem pewien, jaki jest adres URL żądania i jaki jest docelowy adres URL interfejsu API. Upewnij się, że oba są w tej samej domenie (w tym poddomenie).

Myślę, że to dobry pomysł, aby wyłączyć sprawdzanie CSRF tylko na trasach API, gdyż mogą zostać wykorzystane przez innych domen natywnych aplikacjach itp

Można to zrobić dodając następujące plik klasy: 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/*', 
    ]; 
} 

Upewnij się, aby edytować Kernal.php wskazać na nową klasę:

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

aby dowiedzieć się więcej, jak laravel nas es CSRF sprawdzić this laracast video

+0

Dziękuję za odpowiedź! Dodałem do zapytania zapytanie i adresy URL api, ponieważ były ukryte w danych sesji. Twoje rozwiązanie działa w celu ominięcia oprogramowania pośredniego csrf, ale wciąż jest tworzonych wiele sesji. Idealnie chciałbym to naprawić, jeśli to możliwe. – bill