Laravel6 ログイン機能を実装する

バージョン `5.8` までは、`php artisan make:auth`というコマンドを実行するだけでログイン機能を実装できましたが、 `6.0` からその手順が変わりました。

今回は`Laravel 6.0`でログイン機能を実装する方法をご紹介します。

追記: Laravel 8 以降は Laravel UI は廃止され Jetstream というパッケージに移行となりました。

- [Docker × Laravel 8 Jetstream でログイン、ユーザー登録、2要素認証を実装する](https://qiita.com/ucan-lab/items/7824d1293fef4698c212)

## 環境

- PHP 7.3
- Laravel 6.0.3

## 実際のソースコード

https://github.com/ucan-lab/laravel60-authentication

GitHubに上げてます。下記の手順で動作確認できます。

```console
$ git clone git@github.com:ucan-lab/laravel60-authentication
$ cd laravel60-authentication
$ docker-compose up -d --build
$ docker-compose exec app composer install
$ docker-compose exec app cp .env.example .env
$ docker-compose exec app php artisan key:generate
$ docker-compose exec app php artisan migrate
$ docker-compose run node npm install
$ docker-compose run node npm run dev
```

http://127.0.0.1:10080

## Laravel 6.0 でのログイン機能実装

### 前準備

```shell-session
$ php artisan migrate
```

Laravelをインストールしてマイグレーションまで実行しておきます。

### laravel/ui インストール

[laravel/ui](https://github.com/laravel/ui)ライブラリをインストールします。

```shell-session
$ composer require laravel/ui 1.*
```

- 変更されるファイル
  - composer.json
  - composer.lock

[composer require laravel/ui ファイル差分](https://github.com/ucan-lab/laravel60-authentication/commit/d0e99e9a23253459f12503a724eda6614083add1)

```shell-session
$ php artisan ui vue --auth

Vue scaffolding installed successfully.
Please run "npm install && npm run dev" to compile your fresh scaffolding.
Authentication scaffolding generated successfully.
```

- 追加されるファイル
  - app/Http/Controllers/HomeController.php
  - resources/js/components/ExampleComponent.vue
  - resources/sass/_variables.scss
  - resources/views/auth/login.blade.php
  - resources/views/auth/passwords/email.blade.php
  - resources/views/auth/passwords/reset.blade.php
  - resources/views/auth/register.blade.php
  - resources/views/auth/verify.blade.php
  - resources/views/home.blade.php
  - resources/views/layouts/app.blade.php
- 変更されるファイル
  - package.json
  - resources/js/app.js
  - resources/js/bootstrap.js
  - resources/sass/app.scss
  - routes/web.php
  - webpack.mix.js

[php artisan ui vue --auth ファイル差分](https://github.com/ucan-lab/laravel60-authentication/commit/39253bd649a77e1cdcf81e1a5668bde1e335aa1a)

```shell-session
$ npm install
$ npm run dev
```

以上で、Laravelログイン画面の実装は完了です。

## スクリーンショット

### `/` Welcome画面

<img width="1174" alt="スクリーンショット 2019-09-13 13.24.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/e123df2f-7508-c57b-6ff3-5be21b93df81.png">

- 右上に `LOGIN` と `REGISTER` のメニューが追加されます。

### `/register` 会員登録画面

<img width="1172" alt="スクリーンショット 2019-09-13 13.19.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/1810f6f9-4585-c29b-7f2b-734ca265c53b.png">

### `/home` ホーム(ダッシュボード)画面

<img width="1173" alt="スクリーンショット 2019-09-13 13.20.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/d05e463b-cef3-956c-b59f-4e8a49b5654f.png">

### `/login` ログイン画面

<img width="1173" alt="スクリーンショット 2019-09-13 13.21.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/94530cea-9b02-d13f-30b0-f46c07539027.png">

### `/password/reset` パスワードリセット画面

<img width="1174" alt="スクリーンショット 2019-09-13 13.21.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/76bcffcb-24a7-d57e-9ca0-7930480ce9bc.png">

## ルーティング

`php artisan ui vue --auth` コマンド実行後のルーティング定義です。

```shell-session
$ php artisan route:list
+--------+----------+----------------------------+------------------+------------------------------------------------------------------------+-------------------------------------------------+
| Domain | Method   | URI                        | Name             | Action                                                                 | Middleware                                      |
+--------+----------+----------------------------+------------------+------------------------------------------------------------------------+-------------------------------------------------+
|        | GET|HEAD | /                          |                  | Closure                                                                | web                                             |
|        | POST     | _ignition/execute-solution |                  | Facade\Ignition\Http\Controllers\ExecuteSolutionController             | Facade\Ignition\Http\Middleware\IgnitionEnabled |
|        | GET|HEAD | _ignition/health-check     |                  | Facade\Ignition\Http\Controllers\HealthCheckController                 | Facade\Ignition\Http\Middleware\IgnitionEnabled |
|        | GET|HEAD | _ignition/scripts/{script} |                  | Facade\Ignition\Http\Controllers\ScriptController                      | Facade\Ignition\Http\Middleware\IgnitionEnabled |
|        | POST     | _ignition/share-report     |                  | Facade\Ignition\Http\Controllers\ShareReportController                 | Facade\Ignition\Http\Middleware\IgnitionEnabled |
|        | GET|HEAD | _ignition/styles/{style}   |                  | Facade\Ignition\Http\Controllers\StyleController                       | Facade\Ignition\Http\Middleware\IgnitionEnabled |
|        | GET|HEAD | api/user                   |                  | Closure                                                                | api,auth:api                                    |
|        | GET|HEAD | home                       | home             | App\Http\Controllers\HomeController@index                              | web,auth                                        |
|        | POST     | login                      |                  | App\Http\Controllers\Auth\LoginController@login                        | web,guest                                       |
|        | GET|HEAD | login                      | login            | App\Http\Controllers\Auth\LoginController@showLoginForm                | 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             | password.update  | 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                                       |
+--------+----------+----------------------------+------------------+------------------------------------------------------------------------+-------------------------------------------------+
```

## 備考

### php artisan ui

```shell-session
$ php artisan ui -h
Description:
  Swap the front-end scaffolding for the application

Usage:
  ui [options] [--] <type>

Arguments:
  type                   The preset type (bootstrap, vue, react)

Options:
      --auth             Install authentication UI scaffolding
      --option[=OPTION]  Pass an option to the preset command (multiple values allowed)
  -h, --help             Display this help message
  -q, --quiet            Do not output any message
  -V, --version          Display this application version
      --ansi             Force ANSI output
      --no-ansi          Disable ANSI output
  -n, --no-interaction   Do not ask any interactive question
      --env[=ENV]        The environment the command should run under
  -v|vv|vvv, --verbose   Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
```

`vue` の他にも、 `react`、`bootstrap`から選択できます。

## 認証の設定ファイル

### config/auth.php

```config/auth.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];
```

## 参考記事

- [Laravel 6.0 authentication](https://laravel.com/docs/6.0/authentication)
  - [Laravel 6.0 認証
](https://readouble.com/laravel/6.0/ja/authentication.html)
- [Laravel 6.0 mix](https://laravel.com/docs/6.0/mix)
  - [Laravel 6.0 アセットのコンパイル(Mix)
](https://readouble.com/laravel/6.0/ja/mix.html)