4

認証されたユーザーがアイテムの所有者であるかどうかを確認するミドルウェアを作成したいと考えています。単一のモデルの場合、コードは簡単で、次のようになります。

    <?php namespace App\Http\Middleware;

    use Closure;

    class Owner {

        public function handle($request, Closure $next)
        {
            $id = $request->segments()[1]; //get the id parameter
            $model = Model::find($id); // find the model from DB

            if(!$item)
              return 'not found'; //if item not found

            //check if authenticated user is owner
            if($item->user_id == \Auth::id()){ 
              return $next($request);
            }else{
              return 'not allowed';
            }
        }
    }

ここで、複数のモデル (ModelX、ModelY、ModelZ) があり、ミドルウェア ハンドル関数を何度も書き直したくないとします。参照モデルをミドルウェアに挿入して、アプリの複数のモデルに対応させるにはどうすればよいですか?

4

2 に答える 2

3

ルート/モデル バインディングでミドルウェア パラメーターを使用できます。投稿リソースがあると仮定しましょう。

ルートを定義します。ミドルウェアは、所有権を確認するリソースを記述するパラメーターを取得します。

Route::get('/post/{post}', ['middleware' => 'owner:post', 'as' => 'post', 'uses' => 'PostController@showPost']);

次に、RouteServiceProvider.php でモデルをバインドします。

$router->bind('post', function ($value) {
   return Post::where('id', $value)->firstOrFail();
});

最後にミドルウェアを作成します。$request->post. リソースの名前をミドルウェアに渡すため、ハンドル メソッドの 3 番目のパラメーターになります。

public function handle($request, Closure $next, $resource)
{
    if ($request->{$resource}->user_id == \Auth::id()) {
      return $next($request);
    }
    return response('not allowed.', 401);
}

プログラムでリソース名を見つけることもできると思いますが、この方法を使用すると、リソース名とルートが異なる場合があります。

于 2015-08-05T09:18:58.093 に答える
3

ルートとミドルウェアのパラメーターを使用できます。

ミドルウェア ( 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);

        $userId = \DB::table($resourceName)->find($resourceId)->user_id;

        if ($request->user()->id != $userId) {
            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']]);
}
于 2015-08-07T09:20:39.743 に答える