laravel 開発日記 第6回 ~ ログイン処理のミドルウェア修正 ~

前回のあらすじ

(1)ユーザーログイン画面から「ユーザー新規登録(Register)」を削除
(2)管理者権限でログインした時のみ、ユーザー新規登録への導線を表示
(3)ユーザー新規登録画面を表示するとき、ユーザー権限を確認して、管理者以外は見せないようにする。

上記(1)完了後、管理者で新規登録画面を開こうとすると、 /homeにリダイレクトされてしまうようになった! なので、新規登録を開いたときの処理を、プログラムの流れを追いながら修正して行こうと思います。

i)ルーティング(/app/Http/routes.php)

Route::controllers([
    'auth' => 'Auth\AuthController',
    'password' => 'Auth\PasswordController',
]);

まず最初に、/auth/registerを開いたとき、 AuthControllerのgetRegisterメソッドを呼ぶことがわかります。

(参考)
■Laravelのルーティング書き方まとめ
http://qiita.com/michiomochi@github/items/de19c560bc1dc19d698c

ii)AuthControllerクラス – コンストラクタ (/app/Http/Controllers/Auth/AuthController.php)
コンストラクタ内にて、下記ミドルウェアが呼び出されてる模様。

$this->middleware('guest', ['except' => 'getLogout']);

‘guest’ミドルウェアってなんでしょう? middlewareを管理しているカーネルを見に行きます。

iii)カーネル(/app/Http/Kernel.php)

protected $routeMiddleware = [
        'auth' => 'App\Http\Middleware\Authenticate',
        'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
        'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
];

ふむふむ。’guest’ミドルウェアは、
App\Http\Middleware\RedirectIfAuthenticatedに紐付られてるようです。

iv)ミドルウェア /app/Http/Middleware/RedirectIfAuthenticated.php

public function handle($request, Closure $next)
{
    if ($this->auth->check())
    {
        return new RedirectResponse(url('/home'));
    }
    return $next($request);
}

ふむ、ログイン状態をチェックして、
⇒ ログインしてる場合は、/homeに移動。
⇒ ログインしてない場合は、続行。
ということですね。 /homeというアドレスは、本アプリでは/に移動しているので、 以下のように書き換えました。

return new RedirectResponse(url('/'));

ここで、ii)AuthControllerクラス – コンストラクタまで戻ります。

ii)AuthControllerクラス – コンストラクタ (/app/Http/Controllers/Auth/AuthController.php)

$this->middleware('guest', ['except' => 'getLogout']);

ミドルウェアを呼び出す際の例外が書かれているので、 ここにgetRegister(新規登録画面を開く)と、 postRegister(新規登録を実行する)を追加します。

$this->middleware('guest', ['except' => [ 'getLogout','getRegister','postRegister' ]]);

これで、ユーザー新規登録画面表示、およびユーザー登録についても ログインチェックなしで表示できるようになりました。 次に、admin権限をもつ場合のみユーザー新規登録画面を開けるようにします。 コンソールから、以下コマンドでミドルウェア作成

php artisan make:middleware IsUserAdmin

このミドルウェアをカーネルに登録

【作業ファイル:/app/Http/Kernel.php】

protected $routeMiddleware = [
    'auth' => 'App\Http\Middleware\Authenticate',
    'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
    'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
    'IsUserAdmin' => 'App\Http\Middleware\IsUserAdmin',    //追加
];

クラスにもミドルウェアを追加します。

【作業ファイル:/laravel_staging/app/Http/Controllers/Auth】

public function __construct(Guard $auth, Registrar $registrar)
{
    $this->auth = $auth;
    $this->registrar = $registrar;

    $this->middleware('guest', [ 'except' => ['getLogout','getRegister','postRegister'] ]);
    $this->middleware('IsUserAdmin', [ 'only' => 'getRegister','postRegister' ]);    //追加
}

次、ミドルウェアファイルの修正

【作業ファイル:/laravel_staging/app/Http/Middleware】

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\RedirectResponse;

use Illuminate\Support\Facades\Auth;

class IsUserAdmin {

    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;

    /**
     * Create a new filter instance.
     *
     * @param  Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (Auth::user()->level != 'admin')
        {
            return new RedirectResponse(url('/'));
        }
        return $next($request);
    }
}

ログイン中のユーザーネームを取得するため、Authファサードを呼び出してます。

use Illuminate\Support\Facades\Auth;

ファサード呼出し後は、

Auth::user()

で、ログイン中のユーザーの情報を取得できます。

では、動作チェックしてみましょう。 管理者以外でログインして・・・、正常に動いた。 管理者でログインして新規ユーザー登録画面開いて、 情報入力、そして登録・・・ と、ここでエラー! また、/homeにリダイレクトされて、/homeなんてないよ!って言われちゃいました。

ちなみに、データベースを見る限りでは、登録までは完了している模様。 では、再びプログラムの流れを追ってみます。 新規ユーザー登録処理は、AuthコントローラークラスのpostRegisterメソッドに書かれてるはず・・・ しかし、 /app/Http/Controllers/Auth/AuthController.php には、どこにもpostRegisterメソッドがありません。 うーん、困った。

use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
(中略)
use AuthenticatesAndRegistersUsers;

上記記述があるので、下記ファイルをトレイトで呼出ししているんだろうとは思うのですが、このファイルを修正しても変化なし・・・。 キャッシュしてるのだろうか・・・。
/vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesAndRegistersUsers.php なんにせよ、/vendorフォルダ以下のファイルは、可能な限り触りたくない。ということで、グーグル先生に聞いてみたところ、回答を発見。

■Laravel 5 registration / controller / model (Laracasts)
https://laracasts.com/discuss/channels/general-discussion/laravel-5-registration-controller-model

上記を参考に、以下記述を追加しました。

【作業ファイル:/app/Http/Controllers/Auth/AuthController.php】

//リダイレクト先の変更
protected $redirectTo = '/';

ステージングを確認したところ、問題なく/にリダイレクトされました。 すっきりはしないですが、とりあえず問題は解決したので、 今回は、ここまでとします。

いつか、もっとPHPレベルがあがったところで、この問題解決するぞーと誓いつつ、今回はここまでとします。

“laravel 開発日記 第6回 ~ ログイン処理のミドルウェア修正 ~” への 2 件のフィードバック

  1. 始めまして、最近LARAVELで開発を始めたものです。
    ログイン後homeに飛ばさず、元いたページに戻す場合はどのように書いたらよろしいでしょうか?

    環境LARAVEL5

    1. コメントどうもです。

      ログイン後のリダイレクト先は、
      /app/Http/Controllers/Auth/AuthController.php
      のクラス内で、
      protected $redirectTo = ‘/’;
      等で指定すればOKです。
      あとは、ミドルウェアでログイン確認するときにセッション変数とかにurlを登録して・・・

      って、思ったのですが、
      今、テスト環境でためしたところ、特に何も設定してないのですが、
      ログイン前のURLにリダイレクトされた・・・。
      いつのまにか仕様が変わったのだろうか・・・?

      調査して、わかったら記事にまとめますね。
      期待せずにお待ちください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です