根据 id(laravel、数据透视表)动态保护路由


Protect routes dynamically, based on id (laravel, pivot table)

这个话题在这里讨论了很多,但我不明白。

我想用数据透视表(user_customer_relation、user_object_relation (...))保护我的路由,但我不明白,如何正确应用过滤器。

Route::get('customer/{id}', 'CustomerController@getCustomer')->before('customer')

现在我可以向之前过滤器添加一些值

->before('customer:2') 

如何动态执行此操作?

在过滤器中,我可以执行以下操作:

if(!User::hasAccessToCustomer($id)) {
    App::abort(403); 
}

在hasAccessToCustomer函数中:

public function hasCustomer($id) {
    if(in_array($id, $this->customers->lists('id'))) {
        return true;
    }
    return false;
}

如何将客户 ID 正确传递到筛选器?

不能将路由参数传递给筛选器。但是,您可以使用Route::input()从应用程序中的几乎任何地方访问路由参数:

$id = Route::input('id');

优化

public function hasCustomer($id) {
    if($this->customers()->find($id)){
        return true;
    }
    return false;
}

甚至

public function hasCustomer($id) {
    return !! $this->customers()->find($id)
}

(双!!会将null/Customer结果转换为布尔值)

通用方法

这是解决问题的一种可能的、更通用的方法:(虽然没有经过测试)

Route::filter('id_in_related', function($route, $request, $relationName){
    $user = Auth::user();
    if(!$user->{$relationName}()->find($route->parameter('id')){
        App::abort(403);
    }
});

以下是您将如何使用它:

->before('id_in_related:customers')
->before('id_in_related:objects')
// and so on