Laravel配置Policy后访问show页面仍返回403错误如何解决
核心问题原因
你的403报错是由授权参数不匹配、重复授权两个核心问题导致的,具体原因和修复方案如下:
问题点梳理
- 重复授权逻辑冲突:构造方法中已经声明
authorizeResource(ShippingModel::class, 'shippingModel'),资源控制器的show动作会自动触发对应Policy的view方法校验,不需要在show方法中再次手动调用$this->authorize,重复调用时因为参数错误直接触发403。 - 手动授权参数类型错误:
show方法中手动调用的$this->authorize('view', ShippingModel::class)第二个参数传的是模型类名,而非Policy的view方法要求的模型实例。Laravel授权规则中,传类名对应的是viewAny、create这类不需要具体实例的授权方法,传实例才对应view、update这类单模型校验方法,参数不匹配直接返回403。 - 控制器参数与路由参数不匹配:
show方法同时定义了$id和ShippingModel $shippingModel两个参数,如果路由中定义的参数名不是{shippingModel},隐式模型绑定不会生效,自动授权时拿到的是空白模型实例,参数校验失败也会触发403。
修复方案
- 删除
show方法中手动编写的$this->authorize('view', ShippingModel::class);代码,仅保留构造方法的authorizeResource自动授权即可。 - 调整
show方法参数与路由参数保持一致:- 如果路由使用默认资源路由规则(参数为
{shipping}),需要把构造方法authorizeResource的第二个参数改为'shipping',同时调整show方法参数为public function show(ShippingModel $shipping)即可自动完成隐式绑定。 - 如果不想修改路由参数,直接通过$id查询实例即可:
public function show($id) { $shippingModel = ShippingModel::findOrFail($id); return view('pages.warehouse.shipping.show', compact('shippingModel')); }
- 如果路由使用默认资源路由规则(参数为
- 确认
app/Providers/AuthServiceProvider.php中已经正确注册ShippingModel与ShippingModelPolicy的绑定关系,类名、命名空间无拼写错误。
如果需要排查授权细节,可以临时在show方法中添加dd(Gate::inspect('view', $shippingModel))打印授权校验的详细信息,快速定位剩余问题。
内容的提问来源于stack exchange,提问作者Lachlan Young
相关产品推荐
相关产品推荐

