Laravel:路径中间件和策略之间的区别

时间:2016-01-26 16:50:45

标签: php laravel middleware policy

我正在使用laravel开发一个应用程序,我意识到可以使用Policy完成Middleware可以完成的任务。假设我想阻止用户更新路线,如果他/她不是信息的所有者,我可以轻松地从路线检查并且可以从策略中做同样的事情。

所以我的问题是为什么我应该使用policy而不是中间件,反之亦然

3 个答案:

答案 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

当希望将授权分组到一个地方时,有时我会发现这些“策略引用”刀片方法非常有用。