Laravel新增标签逻辑后帖子删改恢复操作授权报错排查
问题描述
完成帖子模块CRUD功能及对应Policy权限逻辑开发后,新增标签模块相关逻辑时出现异常:无法对帖子执行软删除、恢复、强制删除操作。即使将PostPolicy中delete方法的校验逻辑全部移除、直接返回true,系统仍然返回未授权错误。
相关代码片段
PostPolicy 权限逻辑
public function delete(User $user, Post $post) { return true; // if($user->isAdmin) { // return true; // } // // return false; } /** * Determine whether the user can restore the model. * * @param User $user * @param Post $post * @return Response|bool */ public function restore(User $user, Post $post) { if($user->isAdmin || $user->id == $post->user_id) { return true; } return false; } /** * Determine whether the user can permanently delete the model. * * @param User $user * @param Post $post * @return Response|bool */ public function forceDelete(User $user, Post $post) { if($user->isAdmin || $user->id == $post->user_id) { return true; } return false; } /** * Determine whether the user can check the list of archived users. * * @param User $user * @return bool */ public function archived(User $user) { if($user->isAdmin) { return true; } return false; }
帖子控制器destroy方法
/** * Remove the specified resource from storage. * * @param Post $post * @return void * @throws AuthorizationException */ public function destroy(Post $post) { $currentUser = auth()->user(); $this->authorize('delete', $currentUser); $post->delete(); return redirect()->route('dashboard.post.index')->with('warning', 'Archived'); }
AuthServiceProvider 配置
protected $policies = [ User::class => UserPolicy::class, Post::class => PostPolicy::class, Tag::class => TagPolicy::class ];
路由配置
Route::resource('/tag', TagController::class)->except(['create', 'show']);
问题原因
核心错误出在控制器authorize方法的传参逻辑:
authorize方法的第二个参数需要传入当前要执行权限校验的目标模型实例,框架会根据这个模型的类名自动匹配对应的Policy类。- 现有代码传入的是
$currentUser(User模型实例),框架会直接匹配UserPolicy的delete方法做校验,完全不会执行你编写的PostPolicy::delete()逻辑,哪怕PostPolicy里直接返回true也不会生效,自然会抛出未授权错误。 - 该问题和新增标签模块没有直接关联,属于代码编写错误,只是刚好在开发标签模块的节点暴露出来。
修复方案
修改destroy方法内的authorize调用传参,将第二个参数替换为路由模型绑定注入的$post实例即可。框架会自动将当前登录用户传入Policy方法的第一个参数,不需要手动获取传入:
public function destroy(Post $post) { // 修正传参,传入待操作的Post模型实例 $this->authorize('delete', $post); $post->delete(); return redirect()->route('dashboard.post.index')->with('warning', 'Archived'); }
如果帖子恢复、强制删除的相关方法中存在相同的传参错误,按相同逻辑将authorize的第二个参数替换为对应Post实例即可。
内容的提问来源于stack exchange,提问作者Sead Silajdzic
相关产品推荐
相关产品推荐

