Laravel 5.3策略失败时传递AuthorizationException消息 [英] Laravel 5.3 Passing AuthorizationException a message when a Policy fails

查看:233
本文介绍了Laravel 5.3策略失败时传递AuthorizationException消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试寻找一种干净的方法来覆盖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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆