0

モデルで表される Laravel 5.1 のリソースがいくつかあります。モデルはすべて account_id と user_id を持っています。アカウントとユーザーの関係を表す user_account のピボット テーブルがあります。

route.assetなどのリソースコントローラーであるroutes.phpにルートがあります。

これらすべてのコントローラーに対して 1 つのミドルウェアを作成することを検討しています => ['belongstoaccount']

そして、そのミドルウェアでは、次をチェックする必要があります。

ユーザーは account.asset のアカウントに属しています (現在、コントローラーで ->contains() を使用しています。)

アセットの account_id は account->id と一致します。

これらすべてのアセットに対して 1 つのミドルウェアを作成したいと考えています。これは可能ですか?この情報について $request を調べる必要がありますか?

ご指導ありがとうございました。

ジョシュ

4

1 に答える 1

1

これは実際にはそれほど難しくありませんが、ロードされているリソースをミドルウェアが検出できるようにするには、少し設定が必要です。これは、Route-Model Bindingを使用して実現されます

リソース ルートの例:

Route::group(['middleware' => 'BelongsToAccount'], function() {
    Route::resource('asset', 'AssetController');
    Route::resource('liability', 'LiabilityController');
});

ここで、RouteServiceProviderルートがリソースをロードするように、リソースをバインドする必要があります。

   /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @param  \Illuminate\Routing\Router  $router
     * @return void
     */
    public function boot(Router $router)
    {
        parent::boot($router);
        // bound models
        $router->model('asset', 'App\Asset');
        $router->model('liability', 'App\Liability');
    }

次に、ミドルウェアのhandleメソッドに移動してダンプし$request->route()->parameters();ます。パラメーター リストにリソースが表示されます。リクエストで利用可能なリソースのインスタンスを使用して、最後のステップは、ミドルウェアでそれを確認して検証することです。

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Routing\Middleware;
class BelongsToAccount implements Middleware {
    /**
     * 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)
    {
        // get the resource from the route
        $resource = $this->getResource($request);

        if (!empty($resource))
        {
            if ($this->auth->user()->accountId == $resource->accountId)
            {
                return $next($request);
            }
        }
    }

    /**
     * Get resource from route if it exists
     *
     * @param  \Illuminate\Http\Request  $request
     * @return mixed
     */
    public function getResource($request)
    {
        foreach ($request->route()->parameters() as $param)
        {
            if ($param instanceof Model) return $param;
        }

        return null;
    }
}

上記のコードはプラグ アンド プレイではありませんaccountId。現在ログインしているユーザーから値を取得する方法を正確に変更する必要があるかもしれません。のEloquent\Model。見つかると、ミドルウェアが使用するこのリソースを返し、リソースに accountId が既にバインドされていると想定します。

より細かい制御が必要な場合は、ミドルウェアをコントローラーに移動して、__construct動作するコントローラー アクションをより具体的に調整することをお勧めします。ただし、これは routes ファイルでも実現できます。

お役に立てれば!

于 2015-12-30T02:13:57.563 に答える