Laravel Authのusersテーブルの情報を別のテーブルで管理する

# 目的

- 本内容で非常に詰まったため記事としてまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# 実施するに当たっての情報

- usersテーブルで管理されている情報をpeopleテーブルで管理する。
- 単純にusersテーブルで行われていた認証などの機能をpeopleテーブルで行うように切り替える。
- peopleテーブルは新規作成するのでニュアンスは異なるが結果的にはAuthで使用するusersテーブルの名称変更に近い。
- 本説明はDockerなどを使用せず、Macに直接環境構築を行い、そのローカル開発環境での実施を前提としている。
    - ローカル開発環境は下記の方法で構築した。
        - [Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08)
        - [Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9)
- 本作業は下記の記事、またはそれに近い内容でAuthを用いたログイン機能を有しているLaravelのアプリケーションが存在している事を前提にまとめる。
     - [Mac Laravel 7 Authを用いたユーザ登録 ログイン ログアウトなどの機能を作成する](https://qiita.com/miriwo/items/5d4a94e8d2aa06b61530)

# 実施方法概要

- 既に存在するusersテーブルの代わりにpeopleテーブルを用いてAuthのログイン認証などを行う方法を記載する。

1. usersテーブルの代わりになるpeopleテーブルの作成
1. 設定の変更
1. 確認

# 実施方法詳細

- 既に存在するusersテーブルの代わりにpeopleテーブルを用いてAuthのログイン認証などを行う方法を記載する。

1. usersテーブルの代わりになるpeopleテーブルの作成
    1. アプリ名ディレクトリで下記コマンドを実行してpeopleテーブルを操るモデルファイルとマイグレーションファイルを一緒に作成する。(本コマンドを若干詳しくした記事はこちら→[Laravel モデルファイルと一緒にマイグレーションファイルも作成する](https://qiita.com/miriwo/items/e1fa78f042faab13750e))

        ```terminal
        $ php artisan make:model Person --migration
        ```
    1. アプリ名ディレクトリで下記コマンドを実行して先のコマンドで作成されたマイグレーションファイルを開く。(YYYY_MM_DDにはマイグレーションファイル作成日にちが、XXXXXXにはランダムな数字が入る。それぞれの環境にあったコマンドを実行する。)

        ```terminal
        $ vi database/migrations/YYYY_MM_DD_XXXXXX_create_people_table.php
        ```
    1. 開いたYYYY_MM_DD_XXXXXX_create_people_table.phpを下記のように修正する。修正後保存して閉じる。
        - 修正前

            ```アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_people_table.php
            <?php
            
            use Illuminate\Database\Migrations\Migration;
            use Illuminate\Database\Schema\Blueprint;
            use Illuminate\Support\Facades\Schema;
            
            class CreatePeopleTable extends Migration
            {
                /**
                 * Run the migrations.
                 *
                 * @return void
                 */
                public function up()
                {
                    Schema::create('people', function (Blueprint $table) {
                        $table->id();
                        $table->timestamps();
                    });
                }
            
                /**
                 * Reverse the migrations.
                 *
                 * @return void
                 */
                public function down()
                {
                    Schema::dropIfExists('people');
                }
            }
            ```
        -  修正後

            ```アプリ名ディレクトリ/database/migrations/YYYY_MM_DD_XXXXXX_create_people_table.php
            <?php
            
            use Illuminate\Database\Migrations\Migration;
            use Illuminate\Database\Schema\Blueprint;
            use Illuminate\Support\Facades\Schema;
            
            class CreatePeopleTable extends Migration
            {
                /**
                 * Run the migrations.
                 *
                 * @return void
                 */
                public function up()
                {
                    Schema::create('people', function (Blueprint $table) {
                        $table->id();
                        //下記を追加
                        $table->string('name');
                        $table->string('email')->unique();
                        $table->timestamp('email_verified_at')->nullable();
                        $table->string('password');
                        $table->rememberToken();
                        //上記までを追加
                        $table->timestamps();
                    });
                }
            
                /**
                 * Reverse the migrations.
                 *
                 * @return void
                 */
                public function down()
                {
                    Schema::dropIfExists('people');
                }
            }
            ```
    1. アプリ名ディレクトリを下記コマンドで実行してマイグレートを行う

        ```terminal
        $ php artisan migrate
        ```
1. 設定の変更
    1. アプリ名ディレクトリで下記コマンドを実行して先に作成したモデルファイルを開く。

        ```terminal
        $ vi app/Person.php 
        ```
    1. 開いたPerson.phpを下記のように修正する。修正後保存して閉じる。
        - 修正前

            ```アプリ名ディレクトリ/app/Person.php
            <?php
            
            namespace App;
            
            use Illuminate\Database\Eloquent\Model;
            
            class Person extends Model
            {
                //
            }
            ```
        - 修正後

            ```アプリ名ディレクトリ/app/Person.php
            <?php
            
            namespace App;
            //下記を追加と編集
            use Illuminate\Contracts\Auth\MustVerifyEmail;
            //下記を追加
            use Illuminate\Foundation\Auth\User as Authenticatable;
            //下記を追加
            use Illuminate\Notifications\Notifiable;
            
            //下記を修正
            class Person extends Authenticatable
            {
                //下記を追加
                use Notifiable;
            
                /**
                 * The attributes that are mass assignable.
                 *
                 * @var array
                 */
                protected $fillable = [
                    'name', 'email', 'password',
                ];
            
                /**
                 * The attributes that should be hidden for arrays.
                 *
                 * @var array
                 */
                protected $hidden = [
                    'password', 'remember_token',
                ];
            
                /**
                 * The attributes that should be cast to native types.
                 *
                 * @var array
                 */
                protected $casts = [
                    'email_verified_at' => 'datetime',
                ];
                //上記までを追加
            }
            ```
    1. アプリ名ディレクトリで下記を実行してauthの設定ファイルを開く。

        ```terminal
        $ vi config/auth.php 
        ```
    1. 開いた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,
                        'throttle' => 60,
                    ],
                ],
            
                /*
                |--------------------------------------------------------------------------
                | Password Confirmation Timeout
                |--------------------------------------------------------------------------
                |
                | Here you may define the amount of seconds before a password confirmation
                | times out and the user is prompted to re-enter their password via the
                | confirmation screen. By default, the timeout lasts for three hours.
                |
                */
            
                'password_timeout' => 10800,
            
            ];
            ```
        - 修正後

            ```アプリ名ディレクトリ/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' => 'people',
                ],
            
                /*
                |--------------------------------------------------------------------------
                | 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' => 'people',
                    ],
            
                    'api' => [
                        'driver' => 'token',
                        //下記を修正
                        'provider' => 'people',
                        '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,
                    ],
                    //下記を追加
                    'people' => [
                        'driver' => 'eloquent',
                        'model' => App\Person::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,
                        'throttle' => 60,
                    ],
                    //下記を追加
                    'people' => [
                        'provider' => 'people',
                        'table' => 'password_resets',
                        'expire' => 60,
                        'throttle' => 60,
                    ],
                ],
            
                /*
                |--------------------------------------------------------------------------
                | Password Confirmation Timeout
                |--------------------------------------------------------------------------
                |
                | Here you may define the amount of seconds before a password confirmation
                | times out and the user is prompted to re-enter their password via the
                | confirmation screen. By default, the timeout lasts for three hours.
                |
                */
            
                'password_timeout' => 10800,
            
            ];
            ```
    1. アプリ名ディレクトリで下記コマンドを実行してユーザ登録時に呼び出されるメソッドが記載されているファイルを開く。

        ```terminal
        $ vi app/Http/Controllers/Auth/RegisterController.php
        ```
        1. 開いたRegisterController.phpを下記のように修正する。修正後保存して閉じる。
            - 修正前

                ```アプリ名ディレクトリ/app/Http/Controllers/Auth/RegisterController.php
                <?php
                
                namespace App\Http\Controllers\Auth;
                
                use App\Http\Controllers\Controller;
                use App\Providers\RouteServiceProvider;
                use App\User;
                use Illuminate\Foundation\Auth\RegistersUsers;
                use Illuminate\Support\Facades\Hash;
                use Illuminate\Support\Facades\Validator;
                
                class RegisterController extends Controller
                {
                    /*
                    |--------------------------------------------------------------------------
                    | Register Controller
                    |--------------------------------------------------------------------------
                    |
                    | This controller handles the registration of new users as well as their
                    | validation and creation. By default this controller uses a trait to
                    | provide this functionality without requiring any additional code.
                    |
                    */
                
                    use RegistersUsers;
                
                    /**
                     * Where to redirect users after registration.
                     *
                     * @var string
                     */
                    protected $redirectTo = RouteServiceProvider::HOME;
                
                    /**
                     * Create a new controller instance.
                     *
                     * @return void
                     */
                    public function __construct()
                    {
                        $this->middleware('guest');
                    }
                
                    /**
                     * Get a validator for an incoming registration request.
                     *
                     * @param  array  $data
                     * @return \Illuminate\Contracts\Validation\Validator
                     */
                    protected function validator(array $data)
                    {
                        return Validator::make($data, [
                            'name' => ['required', 'string', 'max:255'],
                            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
                            'password' => ['required', 'string', 'min:8', 'confirmed'],
                        ]);
                    }
                
                    /**
                     * Create a new user instance after a valid registration.
                     *
                     * @param  array  $data
                     * @return \App\User
                     */
                    protected function create(array $data)
                    {
                        return User::create([
                            'name' => $data['name'],
                            'email' => $data['email'],
                            'password' => Hash::make($data['password']),
                        ]);
                    }
                }
                ```
            - 修正後

                ```アプリ名ディレクトリ/app/Http/Controllers/Auth/RegisterController.php
                <?php
                
                namespace App\Http\Controllers\Auth;
                
                use App\Http\Controllers\Controller;
                use App\Providers\RouteServiceProvider;
                use App\User;
                //下記を追加
                use App\Person;
                use Illuminate\Foundation\Auth\RegistersUsers;
                use Illuminate\Support\Facades\Hash;
                use Illuminate\Support\Facades\Validator;
                
                class RegisterController extends Controller
                {
                    /*
                    |--------------------------------------------------------------------------
                    | Register Controller
                    |--------------------------------------------------------------------------
                    |
                    | This controller handles the registration of new users as well as their
                    | validation and creation. By default this controller uses a trait to
                    | provide this functionality without requiring any additional code.
                    |
                    */
                
                    use RegistersUsers;
                
                    /**
                     * Where to redirect users after registration.
                     *
                     * @var string
                     */
                    protected $redirectTo = RouteServiceProvider::HOME;
                
                    /**
                     * Create a new controller instance.
                     *
                     * @return void
                     */
                    public function __construct()
                    {
                        $this->middleware('guest');
                    }
                
                    /**
                     * Get a validator for an incoming registration request.
                     *
                     * @param  array  $data
                     * @return \Illuminate\Contracts\Validation\Validator
                     */
                    protected function validator(array $data)
                    {
                        return Validator::make($data, [
                            'name' => ['required', 'string', 'max:255'],
                            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
                            'password' => ['required', 'string', 'min:8', 'confirmed'],
                        ]);
                    }
                
                    /**
                     * Create a new user instance after a valid registration.
                     *
                     * @param  array  $data
                     * @return \App\User
                     */
                    protected function create(array $data)
                    {
                        //下記を修正
                        return Person::create([
                            'name' => $data['name'],
                            'email' => $data['email'],
                            'password' => Hash::make($data['password']),
                        ]);
                    }
                }
                ```
1. 確認
    1. アプリ名ディレクトリで下記コマンドを実行してローカルサーバを起動する。

        ```terminal
        $ php artisan serve
        ```
    1. 下記リンク先にアクセスする。
        - [http://127.0.0.1:8000/register](http://127.0.0.1:8000/register)
    1. 適当にテスト用のアカウント情報を入力して「Register」をクリックする。

        <img width="1311" alt="スクリーンショット 2020-04-17 18.22.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/50f063e2-f967-f30f-b8ff-62af2e4c2c5a.png">

    1. 下記の画面が出る事を確認する。

        <img width="1302" alt="スクリーンショット 2020-04-17 18.27.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8ad88f41-d906-b59d-231f-28c16a81730b.png">

    1. 下記コマンドを実行してターミナルでMySQLにログインする。(MySQLのルートユーザのパスワードを忘れてしまった方はこちら→[MySQL 8.0.18 のrootパスワードを忘れた時のリセット方法](https://qiita.com/miriwo/items/1880e9d2ebcfd3c0e60d))

        ```terminal
        $ mysql -u root -p
        ```
    1. 下記を実行してPeopleテーブルに先ほど新規登録したデータが格納されている事を確認する。(データベース名一覧は`mysql> show databases;`で出力できる)

        ```mysql
        mysql> select * from peopleテーブルがあるデータベース名.people;
        +----+------+---------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
        | id | name | email               | email_verified_at | password                                                     | remember_token | created_at          | updated_at          |
        +----+------+---------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
        |  1 | test | test.test@gmail.com | NULL              | $2y$10$pUYOp5TC6g/F./kRS4.OUu4hP5If0Eo6dI6P.8WydjEbqDDNXEzf6 | NULL           | 2020-04-17 09:26:59 | 2020-04-17 09:26:59 |
        +----+------+---------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
        ```