LoginSignup
4
2

More than 3 years have passed since last update.

Laravelの "This action is unauthorized" を変更する

Last updated at Posted at 2019-09-21

何がしたい?

LaravelにはFormRequestやGateといった「特定のユーザーに特定の操作を許可しない」という権限管理機能が備わっていますが、そこで弾かれたときのエラーメッセージが英語です。多言語対応のLaravelさんならそんなのサクッと変更できるでしょ!と思ったのですが、意外とさっくりできず、グーグル先生もなかなか教えてくれなかったので、僭越ながら穴埋め係させていただきます。

image.png

※この画面はAJAXでのHTTPエラーをswalで表示するという、参画しているアプリのフロント画面です。Laravel標準だと黒い画面か白い画面が出ると思います。

Laravel5.5で実装。ソース見る限りではLaravel5.3~Laravel6.0に対応。

結論

例外のハンドラに追加します。メソッドがすでにある場合は、parent::prepareException($e) の前にコードを追加します。

app\Exceptions\Handler.php
    /**
     * 例外の型を変換する
     */
    protected function prepareException(Exception $e)
    {
        // これを追加
        if( $e instanceof \Illuminate\Auth\Access\AuthorizationException ) {
            $e = new \Illuminate\Auth\Access\AuthorizationException(
                '許可されていません',
                $e->getCode(),
                $e // $eがもともと持っていた情報を失わないように引き継ぐ
            );
        }

        // ↑ あえてデフォルトの動作の前に実行する
        $e = parent::prepareException($e);

        return $e;
    }

image.png

解説

AuthorizationException のデフォルトメッセージ

「This action is unauthorized」というのは AuthorizationException のデフォルトのメッセージなのですが、Laravel6.0でも、それはハードコーディングされています。

Illuminate/Auth/Access/AuthorizationException.php
    public function __construct($message = null, $code = null, Exception $previous = null)
    {
        parent::__construct($message ?? 'This action is unauthorized.', 0, $previous);
        $this->code = $code ?: 0;
    }

エラーや例外処理のメッセージ(例えば「Syntax Error」とか)が多言語対応していないのはふつうなことで、問題はそれをそのまま表示しようとすること。どこかで置き換えしてやるのが良さそうです。

どこで?

prepareException

例外処理ならHander。特定の例外の型変換をするprepareException が適任です。今回は型はそのまま、メッセージだけ載せ替えたい。

ただ、AuthorizationException はデフォルトの型変換として AccessDeniedHttpException に変換されています。

Illuminate/Foundation/Exceptions/Handler.php
    if ($e instanceof AuthorizationException) {
        $e = new AccessDeniedHttpException($e->getMessage(), $e);
    }

だったら、AccessDeniedHttpException のメッセージをカスタマイズすべき? うーむ悩ましいところですが。今回は 「AuthorizationExceptionのデフォルトメッセージを英語にしたい(その後 AccessDeniedHttpException に変換されてどう処理されるかは知らぬ)」という AuthorizationException に固有の問題なので AuthorizationException を変換対象としました。

なので、デフォルトの変換処理 parent::prepareException($e) の前に型変換を行っています。

こんな記事も書いています

Laravelのちょっとマニアックな視点から、誰も書かない記事を書いています(笑
合わせてご覧いただけると幸いです(^^)

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2