初めに
タイトルの通りです。RegisterController
コントローラーやRegisterUsers
トレイトばかりに目が向いていて、ミドルウェアという選択肢を全く考えられなかったことへの戒めに記事に残しておきます。
前提
環境
- PHP
7.4.15
- Laravel
6.20.16
- laravel/ui
1.3.0
今回の認証機能はlaravel/ui
の以下のコマンド
php artisan ui:auth vue
によって提供されるものをそのまま使いました。
結論
先に答えを述べて、それから何故それが答えになるのかの説明をしていきたいと思います。
結論を言いますと、App\Http\Controllers\Auth\RegisterController
クラスのコンストラクタに
public function __construct()
{
$this->middleware('guest');
}
という処理によって、guest
という名前のミドルウェアが適用されているからでした。
guest
ミドルウェアが追加されているコントローラは、認証済みユーザーからはアクセスできないようにミドルウェアによってガードされるようになります。
ではこの処理がどのように動作しているかを見てみましょう。
ミドルウェアguest
guest
ミドルウェアがどんな処理を行うかはApp\Http\Kernel
をみればわかります。
App\Http\Kernel
は
- 適用させるミドルウェアを登録したり
- グループ分けを行ったり
- 今回の
guest
のようにミドルウェアに対して個別に呼び出しを行えるように別名を付けたり
といったミドルウェアに関する情報を扱っています。
App\Http\Kernel
クラスを見てみると、
// 前略
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
// 後略
$routeMiddleware
プロパティに、[ミドルウェア名 => それの実装クラス]
というような形式の連想配列の形で、あるミドルウェアに対してどの実装クラスを実行するかの情報が保存されています。
このプロパティ中のguest
キーに対応するものは\App\Http\Middleware\RedirectIfAuthenticated
というクラスです。
名前からして、認証済みであればリダイレクトを行うという処理を担っていることが明らかですね。
ではこのクラスの実装を見てみましょう。
RedirectIfAuthenticated
クラスの処理
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
}
コメントを省くとこれだけの処理です。
リクエストを受けたときに実行されるメソッドであるhandle()
メソッドの中身を見てみましょう。
まずAuth::guard($guard)->check()
で既にユーザー情報があるかを判断しています。
既にユーザー情報がある、つまりログイン済みであれば
return redirect(RouteServiceProvider::HOME)
でRouteServiceProvider::HOME
にリダイレクトする、という処理を行っています。
この処理から、App\Providers\RouteServiceProvider
クラスのHOME
定数を変更すればリダイレクト先を変更できるということもここから読み取れますね。
ユーザー情報がまだ無ければこのミドルウェアでは何もせず、$next($response)
によって次のミドルウェアへ処理を渡しています。
以上のことから、確かにこのミドルウェアによって認証済みユーザーに対してのアクセスガードが実装されていることが分かりました。
終わりに
認証済みユーザーが/register
にアクセスしたときにリダイレクトする処理は、guest
ミドルウェア、つまり\App\Http\Middleware\RedirectIfAuthenticated
クラスによって提供されていることが分かりました。
ここでは各処理の詳細については深くは追わず、簡略化した説明となっています。
もし各処理の詳細(たとえば、ミドルウェアの実行される流れだったり、リダイレクト関数の実装)が気になる方がいらっしゃいましたら、ぜひ一度laravel
のソースコードを深堀して追ってみるという経験をなさってみてはいかがでしょうか。