2015-04-19 38 views
2

我在創建「所有者」中間件時遇到了麻煩。Laravel 5中間件「所有者」?

例如,我有user_id鍵關聯的ArticlesUser模型。

我想將「所有者」中間件添加到ArticlesController,因此該文章的唯一所有者可以編輯,更新和刪除它。

我一直在尋找這個問題一段時間,但從來沒有找到代碼,這將工作。 其中有些人試圖使它與表單請求一起工作,但我對使用中間件感興趣。

回答

6
  1. 創建中間件:
php artisan make:middleware OwnerMiddleware 
namespace App\Http\Middleware; 

use App\Article; 
use Closure; 
use Illuminate\Contracts\Auth\Guard; 

class OwnerMiddleware 
{ 
    /** 
    * The Guard implementation. 
    * 
    * @var Guard 
    */ 
    protected $auth; 

    /** 
    * Create a new filter instance. 
    * 
    * @param Guard $auth 
    * @return void 
    */ 
    public function __construct(Guard $auth) 
    { 
     $this->auth = $auth; 
    } 

    /** 
    * Handle an incoming request. 
    * 
    * @param \Illuminate\Http\Request $request 
    * @param \Closure $next 
    * @return mixed 
    */ 
    public function handle($request, Closure $next) 
    { 
     $articleId = $request->segments()[1]; 
     $article = Article::findOrFail($articleId); 

     if ($article->user_id !== $this->auth->getUser()->id) { 
      abort(403, 'Unauthorized action.'); 
     } 

     return $next($request); 
    } 
} 
  • 它添加到app\Http\Kernel.php
  • protected $routeMiddleware = [ 
        'owner' => 'App\Http\Middleware\OwnerMiddleware', 
    ]; 
    
  • 使用中間件在你的路線:
  • Route::group(['middleware' => ['owner']], function() { 
        // your route 
    }); 
    
    +0

    你必須創建一個新的'手柄()'每個模型? –

    +0

    這看起來不錯,但它依賴於URL結構no?有沒有什麼方法可以在$ request中獲取模型並比較user_id? – stueynet

    4

    另外,您可以使用路由和middleware parameters,它具有一定的優勢:

    • 即使如果請求結構改變你的中間件仍然可以工作
    • 中間件是可重用的對於型動物資源
    • 你可以使用它裏面的控制器

    這裏的中間件(app/Http/Middleware/AbortIfNotOwner.php):

    <?php 
    
    namespace App\Http\Middleware; 
    
    use Closure; 
    
    class AbortIfNotOwner 
    { 
        /** 
        * Handle an incoming request. 
        * 
        * @param \Illuminate\Http\Request $request 
        * @param \Closure $next 
        * @param string $resourceName 
        * @return mixed 
        */ 
        public function handle($request, Closure $next, $resourceName) 
        { 
         $resourceId = $request->route()->parameter($resourceName); 
    
         $user_id = \DB::table($resourceName)->find($resourceId)->user_id; 
    
         if ($request->user()->id != $user_id) { 
          abort(403, 'Unauthorized action.'); 
         } 
    
         return $next($request); 
        } 
    } 
    

    app\Http\Kernel.php

    protected $routeMiddleware = [ 
        'owner' => 'App\Http\Middleware\AbortIfNotOwner', 
    ]; 
    

    裏面你的路線文件(app/Http/routes.php):

    Route::group(['middleware' => ['owner:articles']], function() { 
        // your route 
    }); 
    

    和可選稱之爲控制器:

    public function __construct() 
    { 
        $this->middleware('owner:articles', ['only' => ['edit', 'update']]); 
    } 
    
    +0

    很聰明!這應該是在laravel – dynamic

    +0

    中默認的問題是它最終會查詢兩次,你可能會更好地在模型綁定之後實現它,或者更新方法中的模型。 – malhal

    +0

    你是什麼意思? 'construct'和'routes'方法是互補的,你不需要同時做兩個。 – Gluten