Laravel 6の「php artisan ui vue –auth」で自動生成されるコードについて Part1

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

前回の記事で、Laravel 6 以降については「php artisan ui vue –auth」コマンドで簡単に認証機能が実装できることを紹介しました。
そこで、今回は自動生成された認証機能のコードを簡単に見ていきたいと思います。

動作確認環境

  • PHP 7.2.15
  • Laravel Framework 6.4.0

ちなみにバージョンは下記のコマンドで調べることができます。

$ php --version
PHP 7.2.15 (cli) (built: Mar  5 2019 02:11:34) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

$ php artisan --version
Laravel Framework 6.4.0

変更・追加されたコードを確認してみる

まず、「php artisan ui vue –auth」コマンドを入力すると下記のファイルの書き換えが行われます。

  • composer.json
  • composer.lock
  • package.json
  • resources/js/app.js
  • resources/js/bootstrap.js
  • resources/sass/app.scss
  • routes/web.php
  • webpack.mix.js

そして、下記のファイルが追加されます。

  • app/Http/Controllers/HomeController.php
  • package-lock.json
  • public/css/
  • public/js/
  • public/mix-manifest.json
  • resources/js/components/
  • resources/sass/_variables.scss
  • resources/views/auth/
  • resources/views/home.blade.php
  • resources/views/layouts/

最初に注目したいのはroutes/web.phpです。
変更内容を確認してみると、下記のコードが追加されています。

Auth::routes();

このコードを追加することで、ルーティングが追加されるようです。
下記のコマンドでルート定義を確認してみます。

$ php artisan route:list
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
| Domain | Method   | URI                    | Name             | Action                                                                 | Middleware   |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
|        | GET|HEAD | /                      |                  | Closure                                                                | web          |
|        | GET|HEAD | api/user               |                  | Closure                                                                | api,auth:api |
|        | GET|HEAD | home                   | home             | App\Http\Controllers\HomeController@index                              | web,auth     |
|        | 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          |
|        | GET|HEAD | password/confirm       | password.confirm | App\Http\Controllers\Auth\ConfirmPasswordController@showConfirmForm    | web,auth     |
|        | POST     | password/confirm       |                  | App\Http\Controllers\Auth\ConfirmPasswordController@confirm            | web,auth     |
|        | POST     | password/email         | password.email   | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail  | web          |
|        | GET|HEAD | password/reset         | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web          |
|        | POST     | password/reset         | password.update  | App\Http\Controllers\Auth\ResetPasswordController@reset                | web          |
|        | GET|HEAD | password/reset/{token} | password.reset   | App\Http\Controllers\Auth\ResetPasswordController@showResetForm        | web          |
|        | GET|HEAD | register               | register         | App\Http\Controllers\Auth\RegisterController@showRegistrationForm      | web,guest    |
|        | POST     | register               |                  | App\Http\Controllers\Auth\RegisterController@register                  | web,guest    |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+

認証系のルーティングがちゃんと定義されてますね。

では、続いてAuth:routes()メソッドが何をしているのかをみていきます。

routes()はIlluminate\Support\Facade\Authに定義されています。
https://github.com/laravel/framework/blob/bbaf5e956cb24512c48fc31129a5e357a09a8ea1/src/Illuminate/Support/Facades/Auth.php#L44

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

まずは、ざっくり説明すると、ここのコードではIlluminate\Routing\Routerクラスの
インスタンスのauth()メソッドを実行しているということになります。

ここで記述されている$appはサービスコンテナのことで、Illiminate\Foundation\Applicationクラスで定義されています。
サービスコンテナはLaravelフレームワーク内でインスタンス管理を担っており、
サービスコンテナに対してメソッド(今回のコードではmake)を実行することで、インスタンスを「要求」します。
※サービスコンテナについては、長くなりますので、また後日記事にしたいと思います。

makeメソッドの引数に解決対象文字列として「router」を指定することで、
Illuminate\Routing\Routerクラスのインスタンスがサービスコンテナから返ってきます。
そして返ってきたインスタンスのauth()メソッドを実行しているというのが大まかな流れです。

なお、「router」という文字列で「Illuminate\Routing\Router」クラスが解決できるのは、
Illuminate\Foundation\ApplicationのコンストラクタでregisterBaseServiceProviders()メソッドを実行しているからです。
https://github.com/laravel/framework/blob/bbaf5e956cb24512c48fc31129a5e357a09a8ea1/src/Illuminate/Foundation/Application.php#L140

/**
* Create a new Illuminate application instance.
*
* @param string|null $basePath
* @return void
*/
public function __construct($basePath = null)
{
    if ($basePath) {
        $this->setBasePath($basePath);
    }
    $this->registerBaseBindings();
    $this->registerBaseServiceProviders();
    $this->registerCoreContainerAliases();
}

このregisterBaseServiceProviders()メソッドで「Illuminate\Routing\RoutingServiceProvider」をサービスプロバイダとして登録しています。
https://github.com/laravel/framework/blob/bbaf5e956cb24512c48fc31129a5e357a09a8ea1/src/Illuminate/Foundation/Application.php#L186

/**
* Register all of the base service providers.
*
* @return void
*/
protected function registerBaseServiceProviders()
{
    $this->register(new EventServiceProvider($this));
    $this->register(new LogServiceProvider($this));
    $this->register(new RoutingServiceProvider($this));
}

※上記のregister()メソッドについては、下記を参照
https://github.com/laravel/framework/blob/bbaf5e956cb24512c48fc31129a5e357a09a8ea1/src/Illuminate/Foundation/Application.php#L588

そして、RoutingServiceProvider内部のregister()メソッドによって、サービスコンテナにrouterというキー(解決対象文字列)でIlluminate\Routing\Routerクラスのインスタンス生成方法が紐づけられます。
Illuminate\Routing\RoutingServiceProviderのコードは下記のとおりです。
https://github.com/laravel/framework/blob/bbaf5e956cb24512c48fc31129a5e357a09a8ea1/src/Illuminate/Routing/RoutingServiceProvider.php#L17

/**
* Register the service provider.
*
* @return void
*/
public function register()
{
    $this->registerRouter();
    $this->registerUrlGenerator();
    $this->registerRedirector();
    $this->registerPsrRequest();
    $this->registerPsrResponse();
    $this->registerResponseFactory();
    $this->registerControllerDispatcher();
}

/**
* Register the router instance.
*
* @return void
*/
protected function registerRouter()
{
    $this->app->singleton('router', function ($app) {
        return new Router($app['events'], $app);
    });
}

話を戻します。

make()メソッドによって、Illuminate\Routing\Routerクラスのインスタンスが返ってきて、それのauth()メソッドを実行しているわけですが、
Illuminate\Routing\Routerクラスのauth()は下記のようなコードになっています。
https://github.com/laravel/framework/blob/bbaf5e956cb24512c48fc31129a5e357a09a8ea1/src/Illuminate/Routing/Router.php#L1143

/**
* 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();
    }
}

認証系のルーティングが設定されてますね。
これが、Auth:routes()メソッドで行われていることです。

続いて、Routeから呼び出されているコントローラについて見ていきましょう。
今回は、/registerをGETで呼び出したときを見ていきます。

/registerをGETで呼び出すと、Auth\RegisterControllerのshowRegistrationFormが実行されます。
なお、showRegistrationFormメソッドはAuth\RegisterControllerでuseしているIlluminate\Foundation\Auth\RegistersUsersに定義されています。

https://github.com/laravel/framework/blob/bbaf5e956cb24512c48fc31129a5e357a09a8ea1/src/Illuminate/Foundation/Auth/RegistersUsers.php#L13

コードを見てみましょう。

    /**
    * Show the application registration form.
    *
    * @return \Illuminate\Http\Response
    */
    public function showRegistrationForm()
    {
        return view('auth.register');
    }

追加された、resources/views/auth/register.blade.phpが表示されます。

続いて、/registerをPOSTで呼び出したときを見ていきます。
/registerをPOSTで呼び出すと、Auth\RegisterControllerのregisterが実行されます。
registerメソッドもAuth\RegisterControllerでuseしているIlluminate\Foundation\Auth\RegistersUsersに定義されています。

https://github.com/laravel/framework/blob/bbaf5e956cb24512c48fc31129a5e357a09a8ea1/src/Illuminate/Foundation/Auth/RegistersUsers.php#L23

コードを見てみましょう。

    /**
    * Handle a registration request for the application.
    *
    * @param \Illuminate\Http\Request $request
    * @return \Illuminate\Http\Response
    */
    public function register(Request $request)
    {
        $this->validator($request->all())->validate();
        event(new Registered($user = $this->create($request->all())));
        $this->guard()->login($user);
        return $this->registered($request, $user)
                        ?: redirect($this->redirectPath());
    }

詳細は省きますが、
まずは、validatorメソッドでPOSTされたデータのバリデーションを行います。
その後、userを作成し、作成したuserでログインします。
ログインが完了したら、TOPヘリダイレクトするという流れです。

長くなりましたので、今回は以上です。

2019年11月12日追記
続きを書きました。
Laravel 6の「php artisan ui vue –auth」で自動生成されるコードについて Part2

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

SNSでもご購読できます。

コメントを残す

*

CAPTCHA