在我的laravel应用程序中,我有多个用户帐户,他们拥有分配给他们的资源。例如,说“付款”。要修改或查看付款,用户可以访问/payment/edit/{payment}
路线(其中payment
是付款ID)。
虽然我有一个auth过滤器来阻止未登录的用户访问此页面,但没有什么可以阻止的,例如,用户1无法编辑用户2的付款。
我是否可以使用过滤器来检查付款(或任何其他资源)属于哪个用户以防止出现此类问题?
[我正在使用Laravel的模型绑定,它自动获取路由指定的模型,而不是使用eloquent在控制器中获取它。]
答案 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
通过策略,您可以控制给定记录是否可以由登录用户编辑。
干杯!