2016-07-04 2 views
0

Может кто-нибудь объяснить мне следующее поведение, когда я включить свои маршруты (Логин, сайт и т.д.) как так:Laravel 5,2 веб промежуточного контроллера Идент вызывает CSRF токен несоответствие

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

Ajax Войти модальное работает правильно однако, когда я попробовать следующее (разрешающих промежуточное программное обеспечение в контроллерах), которые я предпочитаю работать с:

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']); 
    } 
    ... 
} 

TokenMismatchException является trown в VerifyCsrfToken.php линии 67. Насколько мне известно, не должна быть разница в эти два подхода, что я делаю неправильно здесь?

CSRF токен установки:

Базовая планировка:

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

модальные JS:

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

Вы можете подтвердить, что дважды не выполняете промежуточное программное обеспечение ** web **? – TheFallen

+0

Я могу подтвердить, когда я удаляю промежуточное пространство из функции построения authcontroller, он не возвращает несоответствие, но успешно и сеанс не создается. – Jacob

+1

В Laravel 5.2 промежуточное программное обеспечение 'web' автоматически применяется ко всем маршрутам в' routes.php', поэтому вам не следует снова применять промежуточное ПО 'web'. – Rifki

ответ

1

Я дам вам пример работать, взять оттуда идеи, которые помогут Вам:

приложение/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]']); // deleted = 1 
    }); 

приложение/Http/Промежуточное/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'); 
    } 
} 

приложение/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; 
    } 
} 

и, наконец, пример контроллера:

см пространства имен «Billing 'должно быть одинаковым с папкой, иначе вы будете выполнять ручное сглаживание класса в композиторе.

приложение/Http/Контроллеры/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()); 
    } 




Резюме:

  1. , если Вы определили промежуточного программного обеспечения в Route::group - поэтому нет необходимости для вызова внутри промежуточного ПО конструктор. Идея группы маршрутов заключается в том, чтобы освободить вас от повторения кода при написании маршрутов при предоставлении доступа с помощью посредников и т. Д.

  2. Контроллеры auth не должны быть защищены промежуточным программным обеспечением, которое запрещает публичный доступ, если это не приложение для интрасети. поэтому вы можете видеть, что в файле маршрутов я не определял промежуточное ПО для маршрутов префикса «/ auth».

  3. Я не использую токены csrf (я не вижу причин для этого, много лет работы у меня не было, когда csrf был полезен или спас мне жизнь), поэтому я удалил это от Kernel.php.

Смежные вопросы