Laravel阻止用户编辑/查看其他用户的资源

时间:2014-03-24 19:06:13

标签: php laravel

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

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

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

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

3 个答案:

答案 0 :(得分:4)

默认情况下不存在此类过滤器,但您可以轻松创建一个过滤器(具体取决于数据库的设置方式)。在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'));

答案 1 :(得分:1)

一种方法是在每个相关查询中放置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);

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

答案 2 :(得分:0)

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

Siri, call some-contact using scheme-name

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

干杯!