在我的laravel应用程序中,我有多个用户帐户,他们拥有分配给他们的资源。例如,"付款"。要编辑或查看付款,用户将访问/payment/edit/{payment}
路由(其中payment
是付款ID)。
虽然我有一个身份验证过滤器来阻止未登录的用户访问这个页面,但是没有什么可以阻止的,例如,用户1编辑用户2的付款。
是否有一个过滤器,我可以检查哪个用户支付(或任何其他资源)属于防止这种问题?
默认情况下不存在这样的过滤器,但是您可以轻松地创建一个(取决于数据库的设置方式)。在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'));
一种方法是在每个相关查询中放置where语句。虽然不是很漂亮,但它可以工作。
$payment = Payment::where('user_id', '=', Auth::user()->id)->find($id);
也可以像seeARMS建议的那样使用url过滤器,但是我认为它不是很优雅。嵌套这种逻辑的最合乎逻辑的位置是模型本身。一种可能性是使用模型事件,但这只提供了拦截更新、插入或删除语句的选项,而不是选择。这在未来可能会改变。也许你可以使用boot()
事件,但我不确定这是否会起作用。
最后但并非最不重要的是,您可以使用查询范围。
class Payment extends Eloquent {
public function scopeAuthuser($query)
{
return $query->where('user_id', '=', Auth::user()->id);
}
}
和在查询中附加
作用域Payment::authuser()->find($id);
你可以在一个基本模型上这样做,并从它扩展,所以你在所有相关的模型中都有那个方法。
考虑使用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;
}
}
通过策略你可以控制给定的记录是否可以被登录用户编辑。
干杯!