前回の記事で、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