【问题标题】:laravel authorizeResource always denies accesslaravel authorizeResource 总是拒绝访问
【发布时间】:2019-09-26 00:56:41
【问题描述】:

我为 API 端点创建了一个资源控制器。我还为模型创建了相应的策略。

如果我使用方法进行授权检查

$this->authorize('delete', $asset);

然后它按预期工作。但是,如果我将以下内容添加到构造中,我总是会收到 403 禁止。不确定我缺少什么,因为以下内容应该为所有方法应用授权。

$this->authorizeResource(Asset::class, 'asset');

这是我的路线的样子:

Route::group(['middleware' => ['auth:api']], function () {
    Route::Resource('asset', 'AssetsApiController');
});

我的保单是这样注册的:

protected $policies = [
    Asset::class => AssetPolicy::class,
];

我的删除策略方法是

public function delete(User $user, Asset $asset)
{
    return true;
}

API 控制器构造函数如下所示:

public function __construct()
{
    $this->authorizeResource(Asset::class,'asset');
}

API 控制器方法是

public function destroy($assetID)
{
    $asset = Asset::findOrFail($assetID);
    $asset->delete();
}

我的路线是

| GET|HEAD  | api/asset              | asset.index   | App\Http\Controllers\AssetsApiController@index   | api,auth:api                      |
| POST      | api/asset              | asset.store   | App\Http\Controllers\AssetsApiController@store   | api,auth:api,can:create,App\Asset |
| GET|HEAD  | api/asset/create       | asset.create  | App\Http\Controllers\AssetsApiController@create  | api,auth:api,can:create,App\Asset |
| PUT|PATCH | api/asset/{asset}      | asset.update  | App\Http\Controllers\AssetsApiController@update  | api,auth:api,can:update,asset     |
| DELETE    | api/asset/{asset}      | asset.destroy | App\Http\Controllers\AssetsApiController@destroy | api,auth:api,can:delete,asset     |
| GET|HEAD  | api/asset/{asset}      | asset.show    | App\Http\Controllers\AssetsApiController@show    | api,auth:api,can:view,asset       |
| GET|HEAD  | api/asset/{asset}/edit | asset.edit    | App\Http\Controllers\AssetsApiController@edit    | api,auth:api,can:update,asset     |
| GET|HEAD  | assets                 |               | App\Http\Controllers\AssetsController@index      | web                               |                                               

我想我错过了一些东西,但我看不到它,大门在 Telescope 中显示为拒绝。唯一奇怪的是serveNova 中间件似乎是问题的根源。

时间 2019 年 5 月 8 日上午 10:51:37(14m 前)
主机名 core-hosp
能力删除
结果被拒绝
位置 /home/vagrant/code/nova/src/Http/Middleware/ServeNova.php:25
请求 查看请求
标签授权:1

【问题讨论】:

    标签: php laravel-5.8 laravel-nova laravel-middleware


    【解决方案1】:

    我遇到了同样的问题,并通过更改控制器方法的签名解决了它。 默认情况下,控制器接收一个整数$id 来引用模型,而策略直接接收模型实例。我的直觉是无法在控制器和策略之间进行映射。

    所以,我建议尝试将您的控制器方法更改为:

       public function destroy(Asset $asset)
        {
            $asset->delete();
        }
    

    不知道是不是bug?我没有找到有关这些方法类型签名约定的文档。

    2021 年 5 月更新

    您可以将 $id 保留为默认参数,因为您可以通过在找到相关模型实例之后放置授权调用来允许映射 b/t 控制器和策略,如下所示:

    public function destroy($id)
        {   
            $post = Post::find($id);//post instance is created b/4 going through policy.
            $this->authorize('delete',  $post);
            
            $post->delete();
            
            return Post::orderBy('created_at', 'desc')->paginate(3);
        }
    

    【讨论】:

      【解决方案2】:

      我在这里描述了我从这个令人厌烦的问题中学到的教训:https://github.com/laravel/framework/issues/22847#issuecomment-521308861。也许有人会觉得它有用。

      【讨论】:

      • 那是王牌。谢谢
      • 谢谢。顺便说一句,自从您的回复以来,我已经更新了我的答案,添加了第二个关键(难学)课程。 :-)
      【解决方案3】:

      我发现为 authorizeResource 获取正确的模型标识符参数非常繁琐。当参数丢失或未正确传递时,Policy 之前的步骤会抛出错误(不是 Policy 本身,因为请求永远不会到达 Policy)。就我而言,这意味着我的 CheckUserActive 中间件抛出了错误,即使错误出在控制器(而不是中间件)的 Construct 函数中。关于 AuthorizeResource 正在寻找的参数的几点说明:

      1. 必须小写,即使参数以大写形式声明 模型中的案例。
      2. 必须是一个字符串(没有在很多示例中使用的定义 $ 的变量。)
      3. 必须在单引号内。

      例如:

      $this->authorizeResource(Model::class, 'parameter');
      

      【讨论】:

        【解决方案4】:

        我通过删除第二个参数解决了这个问题:

            public function __construct()
        {
            $this->authorizeResource(Admin::class);
        }
        

        【讨论】:

          猜你喜欢
          • 2012-04-23
          • 1970-01-01
          • 2015-05-27
          • 1970-01-01
          • 2020-02-10
          • 2016-07-08
          • 1970-01-01
          • 2018-07-06
          • 1970-01-01
          相关资源
          最近更新 更多