Laravel 5.3策略失败时传递AuthorizationException消息 [英] Laravel 5.3 Passing AuthorizationException a message when a Policy fails
问题描述
我正在尝试寻找一种干净的方法来覆盖AuthorizationException以获取可以在策略失败时传递回的动态字符串.
I'm trying to find a clean way to override the AuthorizationException to take a dynamic string that can be passed back when a policy fails.
我知道我能做的是:
1)用try-catch包裹控制器中的策略,然后重新抛出一个采用特定字符串的自定义异常,这似乎有些冗长
1) Wrap the policy in the controller with a try-catch, then rethrow a custom exception that takes a specific string, which seems a bit verbose
2)abort(403, '...')
返回之前在策略中,由于策略已经在起作用,所以这似乎有点不可靠
2) abort(403, '...')
in the policy prior to returning, which seems a bit hacky since policies are already doing the work
然后在/Exceptions/Handler :: render中,我可以将响应作为JSON发送回
and then in /Exceptions/Handler::render I can send back the response as JSON
是否有更好的方法来执行此操作以在策略失败的响应中获取消息?还是我最好的选择是1或2.
Is there a nicer way to do this to get a message in the response of a policy failure? or is 1 or 2 my best choices.
推荐答案
我注意到,如果您在使用Laravel异常的策略中throw AuthorizationException($message)
会使您跳出该策略,但会继续在控制器中执行,并且不会继续执行到Handler::render
.我以为这是他们以某种方式处理异常的方法,但我找不到他们在哪里执行此操作...因此,如果有人找到发生这种情况的位置,我仍然想知道.
I noticed if you throw AuthorizationException($message)
in a policy using Laravel's exception it jumps you out of the policy, but continues execution in the controller, and doesn't progress to Handler::render
. Which I'm assuming this is them handling the exception somehow, but I couldn't find where they were doing it... so if anyone finds where this is happening I'd still like to know.
如果创建自己的AuthorizationException
并将其抛出,它将按预期停止执行,并放入Handler::render
中,因此我最终将此方法添加到我的策略中:
If you create your own AuthorizationException
and throw it, it will stop execution as expected, and drop into Handler::render
so I ended up adding this method to my policy:
use App\Exceptions\AuthorizationException;
// ... removed for brevity
private function throwExceptionIfNotPermitted(bool $hasPermission = false, bool $allowExceptions = false, $exceptionMessage = null): bool
{
// Only throw when a message is provided, or use the default
// behaviour provided by policies
if (!$hasPermission && $allowExceptions && !is_null($exceptionMessage)) {
throw new \App\Exceptions\AuthorizationException($exceptionMessage);
}
return $hasPermission;
}
仅在\App\Exceptions
中抛出策略的新例外:
New exception for throwing in policies only in \App\Exceptions
:
namespace App\Exceptions;
use Exception;
/**
* The AuthorizationException class is used by policies where authorization has
* failed, and a message is required to indicate the type of failure.
* ---
* NOTE: For consistency and clarity with the framework the exception was named
* for the similarly named exception provided by Laravel that does not stop
* execution when thrown in a policy due to internal handling of the
* exception.
*/
class AuthorizationException extends Exception
{
private $statusCode = 403;
public function __construct($message = null, \Exception $previous = null, $code = 0)
{
parent::__construct($message, $code, $previous);
}
public function getStatusCode()
{
return $this->statusCode;
}
}
处理异常并在Handler::render()
中的JSON响应中提供消息:
Handle the exception and provide the message in a JSON response in Handler::render()
:
public function render($request, Exception $exception)
{
if ($exception instanceof AuthorizationException && $request->expectsJson()) {
return response()->json([
'message' => $exception->getMessage()
], $exception->getStatusCode());
}
return parent::render($request, $exception);
}
,而且我还从登录Handler::report
中删除了它.
and I also removed it from being logged in Handler::report
.
这篇关于Laravel 5.3策略失败时传递AuthorizationException消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!