通过中间件进行Laravel授权

时间:2016-11-01 21:10:48

标签: php laravel laravel-5

我在laravel 5.3中使用以下两个操作创建了一个策略:

class ProjectPolicy {
   ...
   public function index(User $user)
   {
      return true;
   }
   public function create(User $user)
   {
      return true;
   }
   ...
}

然后我尝试通过路由组中间件进行授权:

Route::group(['middleware' => ['can:index,create,App\Project']], function () {
    Route::resource('projects', 'ProjectController');
});

当然我已正确创建了Project模型和控制器,但调用index和create actions总是返回403禁止响应。问题出在哪里?

更新

从路由中间件中删除一个操作,结果是正确的响应。像这样的东西:

Route::group(['middleware' => ['can:index,App\Project']], function () {
    Route::resource('projects', 'ProjectController');
});

2 个答案:

答案 0 :(得分:3)

通过文档查看can中间件并不能真正适应资源。您可以在组上使用多个中间件调用,但这意味着您的使用将需要所有权限才能访问路由。

您的替代方案是:

$this->authorize(new App\Project)添加到控制器中的indexcreate方法。 Laravel将使用反射来根据调用它的方法确定要使用的策略。

或者

在控制器的__construct()方法中,您可以使用:

$this->authorizeResource(App\Project::class); 

这将要求你 在Policy类中创建updateviewdelete方法。这些方法中的每一个都将通过User $user, Project $project,例如

public function view(User $user, Project $project)
{
   return true;
}

仅供参考,如果您使用authorize()取消方法名称或使用authorizeResource(),Laravel会将某些方法名称映射到不同的政策方法,即:

[
  //ControllerMethod => PolicyMethod
    'show'    => 'view',
    'create'  => 'create',
    'store'   => 'create',
    'edit'    => 'update',
    'update'  => 'update',
    'destroy' => 'delete',
];

您可以通过向控制器添加resourceAbilityMap()方法并将其他数组返回到上面的方法来覆盖此方法。

希望这有帮助!

答案 1 :(得分:0)

为此花几个小时... 如果您的控制器方法未将模型作为参数,则还必须覆盖protected function resourceAbilityMap() { Log::info("Inside resourceAbilityMap()"); return array_merge(parent::resourceAbilityMap(), [ //ControllerMethod => PolicyMethod 'index' => 'index', 'search' => 'search' ]); } protected function resourceMethodsWithoutModels(){ return array_merge(parent::resourceMethodsWithoutModels(), [ 'search' ]); }

v1.0-beta