【问题标题】:Laravel prevent users from editing/viewing other users' resourcesLaravel 阻止用户编辑/查看其他用户的资源
【发布时间】:2014-03-24 19:06:12
【问题描述】:

在我的 laravel 应用程序中,我有多个用户帐户,他们拥有分配给他们的资源。例如,说“付款”。要编辑或查看付款,用户将访问/payment/edit/{payment} 路由(其中payment 是付款ID)。

虽然我有一个身份验证过滤器来阻止未登录的用户访问此页面,但没有什么可以阻止,例如,用户 1 编辑用户 2 的付款。

是否有我可以使用的过滤器来检查付款(或任何其他资源)属于哪个用户以防止此类问题?

[我正在使用 Laravel 的模型绑定,它会自动获取路由指定的模型,而不是我使用 eloquent 在控制器中获取它。]

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    默认情况下不存在这样的过滤器,但是您可以轻松创建一个(取决于您的数据库的设置方式)。在 app/filters.php 中,你可以这样做:

    Route::filter('restrictPermission', function($route)
    {
        $payment_id = $route->parameter('payment');
    
        if (!Auth::user()->payments()->find($payment_id)) return Redirect::to('/');
    });
    

    这会将当前登录用户的 payment_id(在您的数据库中)与传递给路由的 {payment} 参数进行比较。显然,根据您的数据库的设置方式(例如,如果 payment_id 在单独的表中),您需要更改条件。

    然后,将过滤器应用于您的路线:

    Route::get('/payment/edit/{payment}', array('before' => 'restrictPermission'));
    

    【讨论】:

    • 这看起来很接近我所追求的。我的表结构是用户有很多付款。所以付款会有一个 user_id。这将如何改变过滤器?假设关系相同,我希望它可以跨多个资源使用。
    • 我更新了我的答案。如果用户有很多付款,您可以简单地调用 payment() 方法并将您需要的任何其他查询链接在一起(在这种情况下,通过它的主键查找付款)。如果没有找到key,它将返回null,从而将用户重定向到'/'。
    • 好的,所以没有办法制作通用过滤器?我需要为每个模型制作一个过滤器吗?
    【解决方案2】:

    一种方法是在每个相关查询中放置一个 where 语句。虽然不是很漂亮,但它确实有效。

    $payment = Payment::where('user_id', '=', Auth::user()->id)->find($id);
    

    也可以使用seeARMS 建议的url 过滤器,但我认为它不是很优雅。嵌套此类逻辑的最合乎逻辑的地方是模型本身。一种可能性是使用model events,但这只会让您选择拦截更新、插入或删除语句,而不是选择。这在未来可能会改变。也许你可以使用boot() 事件,但我不确定这是否可行。

    最后但同样重要的是,您可以使用query scopes

    class Payment extends Eloquent {
    
        public function scopeAuthuser($query)
        {
            return $query->where('user_id', '=', Auth::user()->id);
        }
    }
    

    并在查询中附加范围

    Payment::authuser()->find($id);
    

    您可以在基础模型上执行此操作并从它扩展,因此您在所有相关模型中都有该方法。

    【讨论】:

      【解决方案3】:

      考虑使用 Laravel 策略: https://laravel.com/docs/6.x/authorization#policy-methods

      <?php
      
      namespace App\Policies;
      
      use App\Post;
      use App\User;
      
      class PostPolicy
      {
          /**
           * Determine if the given post can be updated by the user.
           *
           * @param  \App\User  $user
           * @param  \App\Post  $post
           * @return bool
           */
          public function update(User $user, Post $post)
          {
              return $user->id === $post->user_id;
          }
      }
      

      通过策略,您可以控制给定记录是否可以被登录用户编辑。

      干杯!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-29
        • 1970-01-01
        • 2015-05-14
        • 1970-01-01
        • 1970-01-01
        • 2013-07-25
        • 2018-07-28
        • 2021-12-08
        相关资源
        最近更新 更多