我使用的是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
中,您可以定义当X
Exception被抛出时应该做什么。话虽如此,添加下面的代码应该可以达到您的目的:
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);
}