如何更改Laravel策略响应状态码?



我使用的是Laravel 9

我想阻止用户查看其他用户的个人信息。这是我的策略方法

public function viewUser(User $user, User $model)
{
return $user->id === $model->id;
}

这是控制器方法

public function show(User $user)
{
$this->authorize('viewUser', $user);
return view('users.show', compact('user'));
}

如预期的那样显示403

但是我想把状态码改成404,像这样

public function viewUser(User $user, User $model)
{
return $user->id === $model->id
? Response::allow()
: Response::deny(code: 404);
}

仍然显示403而不是404。我在保单上做错了什么?我知道我可以用另一种方法改变回应,但我对Laravel政策本身的问题。

路线
Route::group([
'middleware' => ['auth'],
'prefix' => 'users/{user}',
'as' => 'users.',
], function () {
Route::get('/', [UserController::class, 'show'])->name('show');
});

render()方法中的appExceptionsHandler.php中,您可以定义当XException被抛出时应该做什么。话虽如此,添加下面的代码应该可以达到您的目的:

if ($exception instanceof AuthorizationException) {
$exception = new NotFoundHttpException;
}
return parent::render($request, $exception);

它所做的基本上是检查抛出的异常是否为AuthorizationException (Laravel抛出的策略),如果是这种情况,抛出一个新的NotFoundHttpException (404)。然而,这会将任何和所有authorizationexception更改为404,这可能不是想要的行为。

更新:

在挖掘之后,我发现了一个返回404的封闭提案。

我个人认为策略应该只返回一个403状态码,因为这是正确的代码,有些事情是被禁止的。返回404是不正确的,因为策略没有处理未找到的X资源。

如果你真的想,你可以改变Handler.php。我觉得这不是使用策略的正确方法,但这不是重点。

上述封闭提案中的用户使用请求参数检查路由是否属于某种类型,即产品,返回404而不是403。也许这也可以应用到您的用例中,请在这里查看。希望我讲得很透彻,也许能有所帮助。

从Laravel 9.20开始,它可以通过denyAsNotFound方法实现-链接到docs

public function viewUser(User $user, User $model)
{
return $user->id === $model->id ?
$this->allow() :
$this->denyAsNotFound();
}

denyWithStatus()

的更通用方式
public function viewUser(User $user, User $model)
{
return $user->id === $model->id ?
$this->allow() :
$this->denyWithStatus(404);
}

最新更新