Laravel条件路由过滤器

时间:2014-05-05 18:39:40

标签: laravel

嘿伙计们能帮帮我吗?这个让我发疯了......

我们说我有一种检查用户是否是管理员的方法:

    public function isAdmin()
{
    return Auth::user()->role === 'admin';
}

然后我将它附加到路由过滤器:

    Route::filter('admin', function($route, $request)
{
    if ( ! Auth::user()->isAdmin()) {

        Notification::error('No permission to view this page!');
        return Redirect::back();
    }
});

现在,我只是将它传递给路线组

Route::group(array('before' => 'admin'), function()
  {
    Route::post('users/{id}/update_password', 'UserController@update_password');
    Route::post('users/{id}/delete', 'UserController@force_delete');
    Route::delete('users/{id}', array('as' => 'users.destroy', 'uses' => 'UserController@destroy'));
    Route::post('users/{id}/restore', 'UserController@restore');
    Route::get('users/create', array('as' => 'users.create', 'uses' => 'UserController@create'));
    Route::post('users', array('as' => 'users.store', 'uses' => 'UserController@store'));
    Route::get('users/{id}/edit', array('as' => 'users.edit', 'uses' => 'UserController@edit'));
    Route::put('users/{id}', array('as' => 'users.update', 'uses' => 'UserController@update'));
  });

这里的问题是如何允许用户绕过此过滤器,例如他试图更新它自己的个人资料页面显然是他的不是和管理员? 我只想阻止对非管理员的用户路由的所有访问,但允许用户在他自己的个人资料上编辑/更新等,但允许管理员也这样做。

你能指点我正确的方向吗?

2 个答案:

答案 0 :(得分:3)

您可以在过滤器中查看相关的请求段:

Route::filter('admin', function($route, $request)
{
    if ( ! Auth::user()->isAdmin() && Auth::user()->username !== Request::segment(2)) {
        Notification::error('No permission to view this page!');
        return Redirect::back();
    }
});

答案 1 :(得分:2)

有几种方法可以做到这一点,但是有一个过滤器可以检查当前经过身份验证的用户的请求段,这不是最好的方法。

选择编号1

您只需检查用户是否已获得身份验证(使用auth过滤器),然后在控制器中检查用户是否为管理员,和/或是否为管理员。他们的个人资料。

选择编号2

专门为修改自己个人资料的用户定义辅助路线组,但不遵循/user/{id}/*模式。

Route::group(['before' => 'admin'], function() {
    // admin routes here
}

Route::group(['prefix' => '/me'], function() {
    Route::post('/update_password', 'UserController@update_password');
    Route::post('/delete', 'UserController@force_delete');
    // etc
}

这意味着要编辑自己的个人资料,他们只需转到/me/edit而不是/user/{id}/edit。为了避免重复相同代码或错误因为缺少参数等问题,您可以在控制器中执行类似的操作。

private function getUserOrMe($id)
{
    return $id !== false ? User::find($id) : Auth::user();
}

public function edit($id = false)
{
    $user = $this->getUserOrMe($id);
}

我最近将这种特殊方法用于API。当然,它需要再次定义路线,但是假设您已经使用prefix选项进行了设置,那么它就是一个复制和粘贴作业,另外,还有一些路由管理员会有一个用户不会。

无论哪种方式,过滤器都不打算做复杂的逻辑,而是提供一定程度的基本逻辑和路由保护。识别当前uri是否是当前登录用户的逻辑的逻辑是在控制器中更好地处理的。