Laravel 6のAuth::routes()の意味

Laravel 6の認証機能の有効化でデフォルトで用意されているAuth::routes()の意味を調査したので記す。

導入

PHP Laravel 6で認証機能の有効化には以下のコマンドを実行する。

composer require --dev laravel/ui:^1.0
php artisan ui --auth vue

これらのコマンドで,認証機能を追加するとroutes/web.phpのルート定義に以下の処理が追加される。

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

後半のRoute::get()は分かるとして,Auth::routes()が何をやっているのか気になった。そもそもこのAuth::routes()はいるのか,あるいは順番を変えてもいいのか?

そこでこのAuth::routes()の処理内容を調べた。

Laravelのログイン認証の基本(Authentication)を完全理解する | アールエフェクト」で解説されていたので,これを参考にしながら不足分を実際に自分で確認した。

調査したのはlaravel/framework:6.18.1となる。

Auth::routes()

実際にAuth::routesの定義元を探ると何をやっているかがわかる。

Auth::routes()vendor/laravel/framework/src/Illuminate/Support/Facades/Auth.phpで以下のように定義されている。

class Auth extends Facade
{
...
public static function routes(array $options = []) { static::$app->make('router')->auth($options); }

このstatic::$app->make('router')->auth($options)の処理内容を追いかけて何をやっているのかを理解する。

$app

まず,static::$app->make('router')->auth($options)$appの由来が気になる。

派生元のFacadeからだろうか。実際に確認するとそのとおりで,vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.phpの以下で定義されていた。

abstract class Facade
{
    /**
     * The application instance being facaded.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected static $app;

コメントをみるかぎり,$app\Illuminate\Contracts\Foundation\Applicationのインスタンスらしい。

このApplicationを定義しているファイルはvendor/laravel/framework/src/Illuminate/Contracts/Foundation/Application.phpにある。

use Illuminate\Contracts\Container\Container;

interface Application extends Container
{
...

これが$appの定義元のようだ。

make

$appの諸元がわかったので,今度はstatic::$app->make('router')->auth($options)makeを探る。

これはApplicationの派生元のvendor/laravel/framework/src/Illuminate/Contracts/Container/Container.phpで以下のように定義されている。

namespace Illuminate\Contracts\Container;

use Closure;
use Psr\Container\ContainerInterface;

interface Container extends ContainerInterface
{
...
/** * Resolve the given type from the container. * * @param string $abstract * @param array $parameters * @return mixed * * @throws \Illuminate\Contracts\Container\BindingResolutionException */ public function make($abstract, array $parameters = []);

これはPHPの書き方なのかこのファイルからはmakeの実体が見当たらない。たぶんContractsディレクトリーがヘッダーみたいなものなのだろう。

おそらく,vendor/laravel/framework/src/Illuminate/Container/Container.phpが本体だろう。

    /**
     * Resolve the given type from the container.
     *
     * @param  string  $abstract
     * @param  array  $parameters
     * @return mixed
     *
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function make($abstract, array $parameters = [])
    {
        return $this->resolve($abstract, $parameters);
    }
...
/** * Resolve the given type from the container. * * @param string $abstract * @param array $parameters * @param bool $raiseEvents * @return mixed * * @throws \Illuminate\Contracts\Container\BindingResolutionException */ protected function resolve($abstract, $parameters = [], $raiseEvents = true) {

makeの中で同じクラス内のresolveを呼んでいる。resolveの処理は長いのだが,結局引数の文字列を解決して,該当インスタンスを生成しているようだ。

auth

static::$app->make('router')->auth($options)$app->make('router')/vendor/laravel/framework/src/Illuminate/Routing/Router.phprouterインスタンスを生成していることがわかった。

最後に肝心のRouter::auth($options)の処理内容を確認する。

    /**
     * Register the typical authentication routes for an application.
     *
     * @param  array  $options
     * @return void
     */
    public function auth(array $options = [])
    {
        // Authentication Routes...
        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
        $this->post('login', 'Auth\LoginController@login');
        $this->post('logout', 'Auth\LoginController@logout')->name('logout');

        // Registration Routes...
        if ($options['register'] ?? true) {
            $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
            $this->post('register', 'Auth\RegisterController@register');
        }

        // Password Reset Routes...
        if ($options['reset'] ?? true) {
            $this->resetPassword();
        }

        // Password Confirmation Routes...
        if ($options['confirm'] ??
            class_exists($this->prependGroupNamespace('Auth\ConfirmPasswordController'))) {
            $this->confirmPassword();
        }

        // Email Verification Routes...
        if ($options['verify'] ?? false) {
            $this->emailVerification();
        }
    }

上記の通り,認証用のルート定義 (register, login, logout) とそれに付随する処理がなされていることがわかった。

したがって,認証機能を使うためにroutes/web.phpのコードのどこかにAuth::route()は必要なようだ。これを見る限り特に順番などは関係ないので,任意の場所に配置すればよいだろう。

結論

Laravel 6で認証機能を有効にした場合にroutes/web.phpにデフォルトで記述されるAuth::routes()の意味を探った。

結局register, login, logoutのルート定義とその定型処理だった。ただ,Laravelのマニュアルにはここまできちんとした意味までは書かれていなかったのですっきりした。

$appmakeの定義元が抽象化されており,実態の特定に思いの外苦労した。こういたライブラリー内コードの調査にも慣れていきたい。

コメントを残す

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