Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

標準認証で使われているミドルウェアguestとwebはどこで指定されている? - Laravelコードリーティング

More than 1 year has passed since last update.

趣旨 & 前置き

Laravel5.6のコードを読んでいきます。
Laravel標準の認証では、認証済み(ログイン済み)の状態でログインページにアクセスすると、ログイン後のトップページにリダイレクトします。

認証について解説するページは多いですが、このあたりの動きを解説しているページってみたことないので、書いてみようと思いました。

確認する環境はHomesteadでLaravelをインストールし、

php artisan make:auth
php artisan migrate

だけやった状態だと思います(うろ覚え)

Let's コードリーディング!

ログインしている場合にログイン後のトップページにリダイレクトする処理はApp\Http\Middleware\RedirectIfAuthenticatedクラスに書かれています。

RedirectIfAuthenticatedクラス

public function handle($request, Closure $next, $guard = null)
{   
    if (Auth::guard($guard)->check()) {
        return redirect('/home');
    }   

    return $next($request);
}

認証しているかチェックして、認証していたら/homeにリダイレクトしています。
これが「認証済み(ログイン済み)の状態でログインページにアクセスすると、ログイン後のトップページにリダイレクトする」処理です。(guardなどの細かい説明についてはここではしません。)

さて、問題はこのRedirectIfAuthenticatedクラスがどのように呼び出されているかです。
ネームスペースでわかる通り、RedirectIfAuthenticatedクラスはミドルウェアです。どこかでこのミドルウェアを指定する箇所があるはずです。探してみましょう。

Kernelクラス

開発中のアプリケーションで利用されるミドルウェアはApp\Http\Kernelクラスに記述します。
該当部分を抜粋します。

protected $routeMiddleware = [
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
];

RedirectIfAuthenticatedクラスはguestという名前で登録されているようです。

ルーティングの確認

guestという名前のミドルウェアがどのルーティングで利用されているのかを確認するために、ルーティングを確認してみましょう。

まず、routes/web.phpをみてみます。

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

これだとなんだかよくわかりませんね。
なので以下のコマンドでルーティングの確認をしてみましょう。

php artisan route:list

ルーティングの一覧が表示されるかと思います。
今回関連する部分を抜粋します。

Domain Method URI Name Action Middleware
GET/HEAD home home App\Http\Controllers\HomeController@index web
GET/HEAD login login App\Http\Controllers\Auth\LoginController@showLoginForm web,guest
POST login App\Http\Controllers\Auth\LoginController@login web,guest
POST logout logout App\Http\Controllers\Auth\LoginController@logout web
POST password/email password.email App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail web,guest
GET/HEAD password/reset password.request App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm web,guest
POST password/reset App\Http\Controllers\Auth\ResetPasswordController@reset web,guest
GET/HEAD password/reset/{token} password.reset App\Http\Controllers\Auth\ResetPasswordController@showResetForm web,guest
GET/HEAD register register App\Http\Controllers\Auth\RegisterController@showRegistrationForm web,guest
POST register App\Http\Controllers\Auth\RegisterController@register web,guest

guestミドルウェアが利用されていますね。ミドルウェアが利用されているミドルウェアの指定はControllerのコンストラクタでも可能ですから、LoginControllerクラス / RegisterControllerクラス/ResetPasswordControllerクラス/ForgotPasswordControllerクラスを覗いてみましょう。

LoginControllerクラス / RegisterControllerクラス / ResetPasswordControllerクラス / ForgotPasswordControllerクラス

App\Http\Controllers\Auth\LoginControllerクラスのコンストラクタをみてましょう。

public function __construct()
{   
    $this->middleware('guest')->except('logout');
}

App\Http\Controllers\Auth\RegisterControllerクラス、App\Http\Controllers\Auth\ResetPasswordControllerクラス、App\Http\Controllers\Auth\ForgotPasswordControllerクラスのコンストラクタも同じように見てみます。

public function __construct()
{   
    $this->middleware('guest');
} 

ありました。guestミドルウェア = RedirectIfAuthenticatedクラスを指定しています。これで「認証済み(ログイン済み)の状態でログインページにアクセスすると、ログイン後のトップページにリダイレクトする」仕組みが理解できたと思います。

webミドルウェア

ルーティングの一覧のところにwebというミドルウェアグループも指定されていましたが、これについてもどこで指定されているのか確認してみましょう。

webミドルウェアグループはKernelクラスに以下のように記述されています。

protected $middlewareGroups = [ 
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ]
];

webミドルウェアグループがどこで指定されているのかは、実はドキュメントにちゃんと書いてあります。このへんです。(突然の大雑把)

Tip!! RouteServiceProviderにより、routes/web.phpファイルでは、webミドルウェアグループが自動的に適用されます。

そう、App\Providers\RouteServiceProviderクラスで指定されているのです。

RouteServiceProviderクラス

例によってRouteServiceProviderクラスの該当箇所を抜粋してみます。

public function map()
{
    $this->mapApiRoutes();
    $this->mapWebRoutes();
}   

protected function mapWebRoutes()
{   
    Route::middleware('web')
         ->namespace($this->namespace)
         ->group(base_path('routes/web.php'));
} 

ここでwebミドルウェアグループを指定していますね!
このコードが示す通り、routes/web.phpに記述されたルーティングは基本的にwebミドルウェアが利用されるようです。

終わりに

間違ってたら指摘オナシャス。

yamaji_daisuke
ニートエンジニア。去年くらいはもっぱらPHP/Laravelでサーバーサイドやってました。最近はPython3でAIのお勉強している文系デベロッパーです。上流から下流まで全部やるのが好き。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away