我正在使用laravel开发一个应用程序,我意识到可以使用Policy
完成Middleware
可以完成的任务。假设我想阻止用户更新路线,如果他/她不是信息的所有者,我可以轻松地从路线检查并且可以从策略中做同样的事情。
所以我的问题是为什么我应该使用policy
而不是中间件,反之亦然
答案 0 :(得分:43)
我目前正在通过一个带有我的角色,权限和路线的小型重构,并问自己同样的问题。
在表面层面,看起来真正的中间件和策略执行相同的一般想法。检查用户是否可以做他们正在做的事情。
此处参考laravel docs ......
<强>中间件强> &#34;我可以看到这个吗?我可以去这里吗?&#34;
HTTP中间件提供了一种过滤HTTP的便捷机制 请求进入您的申请。例如,Laravel包含一个 验证应用程序用户的中间件是 认证。如果用户未经过身份验证,则中间件将进行身份验证 将用户重定向到登录屏幕。但是,如果用户是 经过身份验证后,中间件将允许请求继续 进一步进入申请。
当然,可以编写额外的中间件来执行各种操作 除身份验证之外的任务CORS中间件可能是 负责为所有回复添加正确的标题 你的申请。日志记录中间件可能会记录所有传入的请求 到你的申请。
https://laravel.com/docs/master/middleware#introduction
在我的阅读中,中间件是关于在请求级别运行的。在&#34;这个用户可以看到一个页面吗?&#34;,或者#34;这个用户可以在这里做点什么吗?&#34;
如果是,则转到与该页面关联的控制器方法。有趣的是,中间件可能会说,&#34;是的,你可能会去那里,但我会写下你要去的地方。&#34;等
一旦完成。它没有更多的控制权或说出用户在做什么。另一种方式我认为它是中间人。
<强>策略强> &#34;我可以这样做吗?我可以改变这个吗?&#34;
除了提供开箱即用的身份验证服务外, Laravel还提供了一种组织授权逻辑的简单方法 控制对资源的访问。有各种各样的方法和 帮助您组织授权逻辑的助手,以及 我们将在本文档中介绍它们中的每一个。
https://laravel.com/docs/master/authorization#introduction
然而,政策似乎更关心做。用户可以更新任何条目,还是只更新他们的条目?
这些问题似乎适用于控制器方法,其中对资源的所有调用操作都进行了组织。检索此对象,存储或更新文章。
作为tjbb mentioned,中间件可以使路由非常混乱且难以管理。这是我的路线文件中的一个例子:
问题
Route::group(['middleware' =>'role:person_type,person_type2',], function () {
Route::get('download-thing/{thing}', [
'as' => 'download-thing',
'uses' => 'ThingController@download'
]);
});
这在我的路线文件中非常难以阅读!
政策的另一种方法
//ThingController
public function download(Thing $thing)
{
//Policy method and controller method match, no need to name it
$this->authorize($thing);
//download logic here....
}
答案 1 :(得分:17)
路由中间件允许您将请求处理应用于大范围的路由,而不是在每个控制器操作中重复代码 - 检查身份验证和重定向来宾就是一个很好的例子。控制器包含对特定路由/操作唯一的逻辑 - 您可以使用中间件,但是您需要为每个路由的逻辑分别使用中间件,这一切都会变得非常混乱。
策略/功能只是检查用户权限的一种方式 - 您可以从控制器,中间件或其他任何位置查询它们。它们只返回true或false,因此它们不等同于控制器或中间件。大多数时间的功能是将用户与另一个模型进行比较,这个模型将根据发送到控制器操作的标识符进行加载,但也可能有一些应用程序也可用于中间件。
答案 2 :(得分:0)
我问自己同样的问题。在实践中,我主要使用中间件。 我最常见的用法是仅允许特定用户授权,例如:
public function update(User $user, user $model)
{
return $user->id === $model->id;
}
尽管,即使在上述实例中,是的,没有它也可以做,并在控制器中编写自己的逻辑来完成相同的事情。
我还喜欢before方法,该方法用于允许管理员获得模型的完全特权,例如:
public function before($user, $ability)
{
if ($user->admin === 1) {
return true;
}
}
但是,为什么我开始在某些Laravel项目上使用策略的主要原因是因为您可以使用Blade进行操作。如果您发现自己多次在刀片文件中为同一用户授权设置权限(例如,显示一个编辑按钮),则策略可能会变得非常有用,因为您可以对它们(或更多)执行以下操作:
@can('update', $post)
<button class="btn btn-primary">Edit Post</button>
@endcan
@cannot('create', App\Models\Post::class)
<div class="alert alert-warning">You are not allowed to create a post</div>
@endcannot
当希望将授权分组到一个地方时,有时我会发现这些“策略引用”刀片方法非常有用。