我在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');
});
答案 0 :(得分:3)
通过文档查看can
中间件并不能真正适应资源。您可以在组上使用多个中间件调用,但这意味着您的使用将需要所有权限才能访问路由。
您的替代方案是:
将$this->authorize(new App\Project)
添加到控制器中的index
和create
方法。 Laravel将使用反射来根据调用它的方法确定要使用的策略。
或者
在控制器的__construct()
方法中,您可以使用:
$this->authorizeResource(App\Project::class);
这将要求你
在Policy类中创建update
,view
和delete
方法。这些方法中的每一个都将通过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