前回の記事で、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に定義されています。
コードを見てみましょう。
/** * 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に定義されています。
コードを見てみましょう。
/** * 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