首页 文章

Laravel条件路由过滤器

提问于
浏览
2

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

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

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'));
  });

这里的问题是如何允许用户绕过此过滤器,例如他试图更新 it's own Profiles 页面显然他不是和管理员?我只想阻止对非管理员的用户路由的所有访问,但允许用户在他自己的配置文件上编辑/更新等,但允许管理员也这样做 .

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

2 回答

  • 3

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

    Choice Number 1

    您只需检查用户是否已经过身份验证(使用 auth 过滤器),然后在控制器本身中检查用户是否为管理员,和/或是否是他们的 Profiles .

    Choice Number 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
    }
    

    这意味着要编辑自己的 Profiles ,他们可以简单地转到 /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 选项设置了它们,那么's a copy and paste job, plus, there are routes an admin would have that a user wouldn' t .

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

  • 2

    您可以获取相关的请求段以在过滤器中进行检查:

    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();
        }
    });
    

相关问题