【问题标题】:Laravel Conditional route filterLaravel 条件路由过滤器
【发布时间】:2014-05-05 18:39:39
【问题描述】:

大家好,能帮帮我吗?这个快把我逼疯了……

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

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

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

能否请您指出正确的方向?

【问题讨论】:

    标签: laravel


    【解决方案1】:

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

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

    【讨论】:

      【解决方案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 选项的组设置它们,这是一个复制和粘贴作业,另外,管理员会拥有用户不会的路由' t.

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

      【讨论】:

        猜你喜欢
        • 2015-08-30
        • 2014-07-17
        • 1970-01-01
        • 2012-11-19
        • 2013-09-23
        • 1970-01-01
        • 1970-01-01
        • 2020-08-23
        • 2015-01-26
        相关资源
        最近更新 更多