2016-07-04 9 views
0

mir jemand das folgende Verhalten erklären kann, wenn ich meine Routen ermöglichen (Login, Homepage usw.) wie folgt:Laravel 5.2 Web-Middleware in Auth-Controller verursacht csrf Token Mismatch

Route::group(['middleware' => 'web'], function() { 
    .... 
}); 

Ein Ajax Login modal korrekt funktioniert aber wenn ich versuche, die folgende (ermöglicht Middleware in den Steuerungen), die ich arbeite lieber mit:

class PagesController extends Controller 
{ 
    public function __construct() 
    { 
     $this->middleware('web'); 
    } 
    ... 
} 

class AuthController extends Controller 
{ 
    public function __construct() 
    { 
     $this->middleware('web'); 
     $this->middleware('guest', ['except' => 'logout']); 
    } 
    ... 
} 

A TokenMismatchException ist trown in VerifyCsrfToken.php Linie 67. Mein Wissen gibt sollte keinen Unterschied in diese beiden Ansätze, was bin ich mache ich hier falsch?

csrf Token Setup:

Grundlayout:

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

modal js:

var options = { 
    emulateJSON: true, 
    headers: { 
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') 
    } 
}; 
+0

Können Sie bestätigen, dass Sie die ** Web ** Middleware nicht zweimal ausführen? – TheFallen

+0

Ich kann bestätigen, wenn ich das Middleware-Web von der Authcontroller-Konstrukt-Funktion entfernen, gibt es keine Nichtübereinstimmung, aber Erfolg und keine Sitzung wird erstellt. – Jacob

+1

In Laravel 5.2 wird die 'web'-Middleware automatisch auf alle Routen in' routes.php' angewendet, so dass Sie die 'web'-Middleware nicht erneut anwenden sollten. – Rifki

Antwort

1

Ich gebe Ihnen Beispiel arbeiten, von dort Ideen nehmen, die Ihnen helfen:

App/Http/routes.php:

// all routes that start with: "/auth" are not filtered by any middleware 
Route::group(['prefix' => 'auth'], function() { 
    Route::get('/', ['as' => 'auth', 'uses' => '[email protected]']); 
    Route::post('/', ['as' => 'auth.attempt', 'uses' => '[email protected]']); 
    Route::delete('/', ['uses' => '[email protected]']); 
    Route::any('destroy', ['as' => 'auth.destroy', 'uses' => '[email protected]']); 
}); 

// all routes that start with: "/billing" will be handled by this group (prefix => 'billing') 
// all controllers inside this route group are located in 'Billing' namespace 
// all routes in this group are pre-checked by middleware 'HasAccessToBilling' 
Route::group(['prefix' => 'billing', 'namespace' => 'Billing', 'middleware' => ['App\Http\Middleware\HasAccessToBilling']], function() 
{ 
    Route::any('/', ['as' => 'billing', 'uses' => '[email protected]']); 

    Route::get('profile', ['as' => 'billing.profile', 'uses' => '[email protected]']); 

    // TARIFFS 
    Route::group(['prefix' => 'tariffs'], function() { 
     Route::get('/', ['as' => 'billing.tariffs', 'uses' => '[email protected]']); // showing page with tariffs paginated 
     Route::get('all', ['as' => 'billing.tariffs.all', 'uses' => '[email protected]']); // listing all tariffs with json (see controller) 

     Route::get('create', ['as' => 'billing.tariffs.create', 'uses' => '[email protected]']); // create form 
     Route::post('/', ['as' => 'billing.tariffs.store', 'uses' => '[email protected]']); // creating 

     Route::get('{id}', ['as' => 'billing.tariffs.edit', 'uses' => '[email protected]']); // edit form 
     Route::post('{id}', ['as' => 'billing.tariffs.update', 'uses' => '[email protected]']); // updating 

     Route::get('{id}/activate', ['as' => 'billing.tariffs.activate', 'uses' => '[email protected]']); // active = 1 
     Route::get('{id}/suspend', ['as' => 'billing.tariffs.suspend', 'uses' => '[email protected]']); // active = 0 
     Route::get('{id}/delete', ['as' => 'billing.tariffs.delete', 'uses' => '[email protected]delete']); // deleted = 1 
    }); 

app/Http/Middleware/HasAccessToBilling.php:

<?php namespace App\Http\Middleware; 

use App\Library\Auth; 
use Closure; 
use Illuminate\Http\Request; 

class HasAccessToBilling 
{ 

    /** 
    * Handle an incoming request. 
    * 
    * @param \Illuminate\Http\Request $request 
    * @param \Closure $next 
    * @return mixed 
    */ 
    public function handle(Request $request, Closure $next) 
    { 
     if (Auth::hasAccessTo('billing', $request)) { 
      return $next($request); 
     } 
     return redirect()->route('auth'); 
    } 
} 

app/Library/Auth.php:

<?php namespace App\Library; 

use \App\Models\User; 
use Illuminate\Http\Request; 
use Crypt; 

class Auth 
{ 

    public static function recoverSession(Request $request) 
    { 
     $rememberToken = $request->cookie('remember-token', null); 
     if(is_null($rememberToken)) { 
      return null; 
     } 

     try{ 
      $rememberToken = Crypt::decrypt($rememberToken); 
      $auth = json_decode($rememberToken, true); 
      $request->session()->set('auth', $auth); 
     } 
     catch(\Exception $ex) {} 

     return $request->session()->get('auth'); 
    } 

    public static function hasAccessTo($realm, Request $request) 
    { 
     $auth = $request->session()->get('auth', null); 
     if (is_null($auth)) { 
      $auth = self::recoverSession($request); 
     } 

     return (isset($auth['access_to']))? 
       in_array($realm, $auth['access_to']) 
       : false; 
    } 
} 

und schließlich Beispiel Controller:

siehe Namensraum ‚Billing 'muss mit dem Ordner identisch sein, sonst werden Sie im Composer manuell Klassen-Aliasing durchführen.

app/Http/Controller/Billing/TariffsController.php:

<?php namespace App\Http\Controllers\Billing; 

use Illuminate\Http\Request; 
use Redirect; 
use App\Http\Controllers\Controller; 
use App\Models\Tariff as Model; 

class TariffsController extends Controller 
{ 

    /** 
    * Listing records 
    * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View 
    */ 
    public function index() 
    { 
     $records = Model::paginate(); 
     return view('billing.tariffs.index', compact('records')); 
    } 

    /** 
    * Listing all tariff plans as json 
    * @return \Illuminate\Http\JsonResponse 
    */ 
    public function all() 
    { 
     return $this->ok(Model::all()); 
    } 




Zusammenfassung:

  1. wenn Sie Middleware in Route::group definiert - so dass keine Notwendigkeit für den Aufruf innerhalb Middleware Konstrukteur. Die Idee der Routegruppe besteht darin, Sie davon abzuhalten, Code beim Schreiben von Routen zu wiederholen, wenn Sie Zugriffe mit Middlewares usw. geben.

  2. Auth-Controller dürfen nicht von Middleware geschützt werden, die den öffentlichen Zugriff verweigert, wenn es sich nicht um Intranet-Anwendung handelt. Sie sehen also, dass ich in meiner Routes-Datei keine Middleware für "/ auth" -Präfix-Routen definiert habe.

  3. Ich benutze keine csrf-Token (ich sehe keinen Grund dafür, viele Jahre Arbeit, ich habe nie den Moment, in dem csrf hilfreich war oder mein Leben gerettet), also habe ich entfernt es von Kernel.php.