Laravel 5:多模型中间件“所有者”

时间:2015-06-13 06:39:57

标签: laravel laravel-5 laravel-middleware

我想创建一个中间件来检查经过身份验证的用户是否是该项目的所有者。对于单个模型,代码很简单,看起来像:

    <?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),我不想多次重写中间件句柄功能。 如何在中间件中注入引用的模型以使其适应我的应用程序中的多个模型?

2 个答案:

答案 0 :(得分:3)

您可以将中间件参数与路由/模型绑定结合使用。让我们假设您有一个帖子资源。

您将定义路线。中间件获取一个参数,描述您要检查所有权的资源。

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

然后你将在RouteServiceProvider.php中绑定你的模型:

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

最后你会制作中间件。重要的是要知道绑定在请求对象中可用作$ request-&gt; post。由于您将资源的名称传递给中间件,因此它将成为handle方法中的第三个参数。

//select all inputs in a div with id Money_panel1
$("#Money_panel1 :input").each(function( index ) {

    //if it is a textbox get value
    if( $(this).attr("type")  == "text"  )
      alert( $( this ).val() );

    //if it is radio/checkbox get whether its checked or not
    else if(  $(this).attr("type") == "radio" )
        alert( $(this).is(":checked") );

 });

我想你也可以通过编程方式找到资源名称,但是使用这种方法你的资源名称和路径可能会有所不同。

答案 1 :(得分:3)

您可以使用路线和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);

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