【问题标题】:Laravel: Difference Between Route Middleware and PolicyLaravel:路由中间件和策略之间的区别
【发布时间】:2016-05-03 08:06:37
【问题描述】:

使用 laravel 开发应用程序我意识到可以使用 Policy 完成的操作完全可以使用 Middleware 完成。假设我想阻止用户更新路由,如果他/她不是信息的所有者,我可以轻松地从路由中检查并且可以从策略中执行相同的操作。

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

【问题讨论】:

  • 我认为你应该尝试这样看待它:middleware 用于 authenticatingpolicies 用于授权的使用.

标签: php laravel middleware policy


【解决方案1】:

我目前正在对我的角色、权限和路线进行一次小型重构,并问自己同样的问题。

从表面上看,真正的中间件和策略似乎执行相同的总体思路。检查用户是否可以做他们正在做的事情。

参考这里的 laravel 文档...

中间件 “我可以看看这个吗?我可以去这里吗?”

HTTP 中间件提供了一种方便的过滤 HTTP 的机制 请求进入您的应用程序。例如,Laravel 包含一个 验证应用程序用户的中间件是 认证。如果用户未通过身份验证,中间件将 将用户重定向到登录屏幕。但是,如果用户是 经过身份验证,中间件将允许请求继续进行 进一步进入应用程序。

当然,可以编写额外的中间件来执行各种 除了身份验证之外的任务。 CORS 中间件可能是 负责为所有离开的响应添加正确的标题 你的申请。日志中间件可能会记录所有传入的请求 到您的应用程序。

https://laravel.com/docs/master/middleware#introduction

在我的阅读中,中间件是关于在请求级别操作的。在“这个用户可以看到一个页面吗?”或“这个用户可以在这里做点什么吗?”的术语中。

如果是这样,它会转到与该页面关联的控制器方法。有趣的是,中间件可能会说:“是的,你可以去那里,但我会写下你要去的地方。”等等。

一旦完成。它对用户正在做的事情没有更多的控制权或发言权。我认为它是中间人的另一种方式。

政策 “我可以这样做吗?我可以改变这个吗?”

除了提供开箱即用的身份验证服务外, 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....
}

【讨论】:

  • 'as' => 'download-thing' 有什么作用?我觉得它的作用类似于“在处理此请求的其余部分时充当此模型”。我正在尝试查找有关它的文档,但到目前为止还没有运气。编辑:我找到了。它可以让您“命名”一条路线,以便在生成 URL 或重定向用户时使用。对我来说用处不大:(
  • 很好的答案!该策略的另一个好处是您可以通过can 命令在刀片模板中使用它。
【解决方案2】:

路由中间件允许您将请求处理应用于大量路由,而不是在每个控制器操作中重复代码 - 检查身份验证和重定向访客就是一个很好的例子。相反,控制器包含特定路由/操作独有的逻辑 - 您可以为此使用中间件,但您需要为每个路由的逻辑使用单独的中间件,这一切都会变得非常混乱。

策略/功能只是检查用户权限的一种方式 - 您可以从控制器、中间件或其他任何地方查询它们。它们只返回 true 或 false,因此它们不等同于控制器或中间件。大多数情况下,功能是将用户与另一个模型进行比较,该模型将根据发送到控制器操作的标识符进行加载,但也可能有一些应用程序与中间件一起使用。

【讨论】:

    【解决方案3】:

    我也问过自己同样的问题。在实践中,我主要使用中间件。 我最常见的用法是仅允许对特定用户进行授权,例如:

    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 项目中使用策略的主要原因是你可以用刀片做些什么。如果您发现自己在刀片文件中多次为同一用户授权设置权限,例如显示编辑按钮,那么策略可能会变得非常有用,因为您可以对它们执行以下操作(以及更多):

    @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
    

    当我想在一个地方分组授权时,有时我发现这些引用策略的刀片方法非常有用。

    【讨论】:

      猜你喜欢
      • 2015-10-26
      • 1970-01-01
      • 2019-07-14
      • 2020-03-13
      • 2018-06-28
      • 2023-03-29
      • 2020-01-30
      • 2017-10-11
      • 2017-05-19
      相关资源
      最近更新 更多