[英]Models, Resource Controllers and Middleware in Laravel 5.1
我在Laravel 5.1中有几个由模型表示的资源。 这些模型都具有account_id和user_id。 有一个user_account数据透视表,它表示帐户和用户之间的关系。
我在route.php中有我的路由,这些路由是资源控制器,例如route.asset。
我正在为所有这些控制器创建一个中间件,以便可以在=> ['belongstoaccount']之前完成
在该中间件中,应检查:
用户属于account.asset中的帐户(我当前在控制器中使用-> contains()。)
资产的account_id与account-> id相匹配。
我想为所有这些资产制作一个中间件。 这有可能吗? 我应该在$ request中寻找此信息吗?
感谢您的指导,
乔希
这实际上并不算困难,但是中间件确实需要一些设置才能检测到正在加载哪个资源。 这是通过使用路由模型绑定来完成的
资源路由示例:
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
以更具体地调整其对哪个控制器动作进行调整。 不过,您也可以在路由文件中完成此操作。
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.