Laravel5.6 ユーザと管理者の認証を分けて作る

# 目的

- ユーザと管理者とで認証を分ける方法をまとめる。

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| PC | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 5.6.40 | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 前提条件

- 先の実施環境に近い環境が整っていること。
- Laravelは最新バージョン用に構築しているがアプリ作成コマンド実行時に5.6を指定して作成する。

# 前提情報

- DockerやAWSなどは使用せずにMacのローカル環境に直接Laravelアプリを作成する。
- 若干難易度が高い作業であるためなるべくわかりやすい様に丁寧に記載する。
- 本記事の内容を最初から実施していけば誰でもユーザと管理者別々での認証を行えることを目指す。
- 管理者認証情報は管理者名、メールアドレス、パスワードとする。
- 作業複雑化を避けるため管理者用のパスワードはアプリ側から変更できる様にしない。
- 既存のAuth認証コントローラを追記編集して管理者の認証機能を作成する。
- 下記のドキュメントを参考に必要名部分のみを抜粋して実装する。また、説明をより分かりやすくするために若干実装の順番を変更する。
    - [LARAVELアプリで複数の認証ガードを使用する方法](https://pusher.com/tutorials/multiple-authentication-guards-laravel)

# 読後感

- Laravel5.6のでユーザ認証と管理者認証機能のついたアプリを作成することができる。

# 概要

1. データベースの作成
1. Laravelアプリの作成と初期設定
1. ユーザ認証機能作成
1. 管理者情報用テーブルの準備
1. ガードとプロバイダの追加
1. コントローラの修正
1. 認証用ページの作成
1. 認証後遷移ページの作成
1. ルーティングの記載と認証後遷移ページの設定と例外時の処理の記載
1. 確認

# 詳細

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

        ```terminal
        $ mysql -u root -p
        ```
    1. 下記SQLを実行して「multi_auth」データベースを作成する。

        ```sql
        create database multi_auth;
        ```
    1. 下記SQLを実行してデータベース一覧を出力して「multi_auth」が含まれていることを確認する。確認後、MySQLをログアウトする。

        ```sql
        show databases;
        ```
1. Laravelアプリの作成と初期設定
    1. Laravelアプリを作成する任意のディレクトリに移動する。
    1. 下記コマンドを実行して「multi_auth」というLaravel5.6のアプリを作成する。(完了まで時間がかかる可能性があるので少し待機する。)

        ```terminal
        $ composer create-project laravel/laravel multi_auth "5.6.*"
        ```
    1. 下記コマンドを実行して作成されたアプリ名ディレクトリに移動する。以後のコマンドは特に記載がない場合、このmulti_authディレクトリ内部で実行する物とする。
    
        ```terminal
        $ cd multi_auth
        ```
    1. 下記コマンドを実行して.envファイルを開く。

        ```terminal
        $ vi .env
        ```
    1. 下記の様に.envファイルのデータベースの記述を修正する。

        ```multi_auth/.env
        DB_DATABASE=multi_auth
        DB_USERNAME=root
        DB_PASSWORD=mysql -u root -pコマンドを実行した際に入力したパスワード
        ```
    1. 修正後の.envファイルの全体の内容を記載する。

        ```multi_auth/.env
        APP_NAME=Laravel
        APP_ENV=local
        APP_KEY=アプリキーの記載は各個人で異なります。
        APP_DEBUG=true
        APP_URL=http://localhost
        
        LOG_CHANNEL=stack
        
        DB_CONNECTION=mysql
        DB_HOST=127.0.0.1
        DB_PORT=3306
        DB_DATABASE=multi_auth
        DB_USERNAME=root
        DB_PASSWORD=皆さんの環境のMySQLのrootユーザのパスワード
        
        BROADCAST_DRIVER=log
        CACHE_DRIVER=file
        QUEUE_CONNECTION=sync
        SESSION_DRIVER=file
        SESSION_LIFETIME=120
        
        REDIS_HOST=127.0.0.1
        REDIS_PASSWORD=null
        REDIS_PORT=6379
        
        MAIL_MAILER=smtp
        MAIL_HOST=smtp.mailtrap.io
        MAIL_PORT=2525
        MAIL_USERNAME=null
        MAIL_PASSWORD=null
        MAIL_ENCRYPTION=null
        MAIL_FROM_ADDRESS=null
        MAIL_FROM_NAME="${APP_NAME}"
        
        AWS_ACCESS_KEY_ID=
        AWS_SECRET_ACCESS_KEY=
        AWS_DEFAULT_REGION=us-east-1
        AWS_BUCKET=
        
        PUSHER_APP_ID=
        PUSHER_APP_KEY=
        PUSHER_APP_SECRET=
        PUSHER_APP_CLUSTER=mt1
        
        MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
        MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
        ```
    1. 下記コマンドを実行して初期マイグレーションファイルをマイグレートする。

        ```terminal
        $ php artisan migrate
        ```
    1. 下記コマンドを実行してローカルサーバを起動する。

        ```terminal
        $ php artisan serve
        ```
    1. 下記にアクセスしてLaravelの初期画面が表示されることを確認する。
        - [http://localhost:8000/](http://localhost:8000/)

            ![Laravel-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/ca4135f5-c29f-69ba-bed7-01d9735a683b.png)

1. ユーザ認証機能作成
    1. 下記コマンドを実行してユーザ認証機能を作成する。

        ```terminal
        $ php artisan make:auth
        ```
    1. 下記コマンドを実行してローカルサーバを起動する。

        ```terminal
        $ php artisan serve
        ```
    1. 下記にアクセスしてLaravelの初期画面を開く。
        - [http://localhost:8000/](http://localhost:8000/)

            ![Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/4e37a799-774a-1d25-3c8f-4dfb9a8929e6.png)

    1. 右上の「REGISTER」をクリックする。

        ![Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c4e85e52-27f5-1700-896e-c1a94b572f1a.png)
    
    1. 各種情報を入力して「Register」をクリックする。

        ![Laravel-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d0f26126-bc58-25a8-e590-f09329c102bf.png)
        
    1. 「Register」をクリック後、下記の画面に遷移することを確認する。

        ![Laravel-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/bd71c3ee-b726-d216-7a04-18ea88c13d4e.png)


1. 管理者情報用テーブルの準備
    1. 下記コマンドを実行してAdminモデルファイルとadminsテーブル作成用マイグレーションファイルを作成する。

        ```terminal
        $ php artisan make:model Admin -m
        ```
    1. 下記コマンドを実行して先に作成したマイグレーションファイルを開く。(YYYY_MM_DD_XXXXXXの部分はマイグレーションファイル作成日により異なる。)

        ```terminal
        $ vi database/migrations/YYYY_MM_DD_XXXXXX_create_admins_table.php
        ```
    1. 開いたマイグレーションファイルを下記の様に追記する。

        ```multi_auth/database/migrations/YYYY_MM_DD_XXXXXX_create_admins_table.php
        <?php
        
        use Illuminate\Support\Facades\Schema;
        use Illuminate\Database\Schema\Blueprint;
        use Illuminate\Database\Migrations\Migration;
        
        class CreateAdminsTable extends Migration
        {
            /**
             * Run the migrations.
             *
             * @return void
             */
            public function up()
            {
                Schema::create('admins', function (Blueprint $table) {
                    $table->increments('id');
                    //下記から追加
                    $table->string('name');
                    $table->string('email')->unique();
                    $table->string('password');
                    $table->boolean('is_super')->default(false);
                    $table->rememberToken();
                    //上記までを追加
                    $table->timestamps();
                });
            }
        
            /**
             * Reverse the migrations.
             *
             * @return void
             */
            public function down()
            {
                Schema::dropIfExists('admins');
            }
        }
        
        ```
    1. 下記コマンドを実行して今記載したマイグレーションファイルをマイグレートする。

        ```terminal
        $ php artisan migrate
        ```
    1. 下記コマンドを実行して先に作成したモデルファイルを開く。

        ```terminal
        $ vi app/Admin.php
        ```
    1. 開いたモデルファイルの内容を全て削除し、下記の内容をコピーアンドペーストで記載する

        ```multi_auth/app/Admin.php
        <?php
    
        namespace App;
    
        use Illuminate\Notifications\Notifiable;
        use Illuminate\Foundation\Auth\User as Authenticatable;
    
        class Admin extends Authenticatable
        {
            use Notifiable;
    
            protected $guard = 'admin';
    
            protected $fillable = [
                'name', 'email', 'password',
            ];
    
            protected $hidden = [
                'password', 'remember_token',
            ];
        }
        ```
1. ガードとプロバイダの追加
    1. 下記コマンドを実行しガードとプロバイダを定義しているファイルを開く。

        ```terminal
        $ vi  config/auth.php
        ```
    1. ガードの記載を下記の様に追記する。

        ```multi_auth/config/auth.php
        /*
        |--------------------------------------------------------------------------
        | 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',
            ],
            //下記を追記
            'admin' => [
                'driver' => 'session',
                'provider' => 'admins',
            ],
            //上記までを追記
        ],
        ```
    1. 同ファイル内のプロバイダの記載も追記を行う。

        ```multi_auth/config/auth.php
        /*
        |--------------------------------------------------------------------------
        | 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,
            ],
            //下記を追記する
            'admins' => [
                'driver' => 'eloquent',
                'model' => App\Admin::class,
            ],
            //上記までを追記する
    
            // 'users' => [
            //     'driver' => 'database',
            //     'table' => 'users',
            // ],
        ],
        ```
    1. 追記後の`multi_auth/config/auth.php`のファイルの全体を下記に記載する。

        ```multi_auth/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',
                ],
                //下記を追記する
                'admin' => [
                    'driver' => 'session',
                    'provider' => 'admins',
                ],
                //上記までを追記する
            ],
        
            /*
            |--------------------------------------------------------------------------
            | 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,
                ],
                //下記を追記する
                'admins' => [
                    'driver' => 'eloquent',
                    'model' => App\Admin::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,
                ],
            ],
        
        ];
        ```
1. コントローラの修正
    1. 下記の二つのコントローラを修正する。
        - `multi_auth/app/Http/Controllers/Auth/LoginController.php`
        - `multi_auth/app/Http/Controllers/Auth/RegisterController.php`
    1. 下記コマンドを実行してログインを司るコントローラファイルを開く。

        ```terminal
        $ vi app/Http/Controllers/Auth/LoginController.php
        ```
    1. 開いたコントローラファイルを下記の様に修正する。

        ```app/Http/Controllers/Auth/LoginController.php
        <?php
        
        namespace App\Http\Controllers\Auth;
        
        use App\Http\Controllers\Controller;
        use Illuminate\Foundation\Auth\AuthenticatesUsers;
        
        // 下記を追記する
        use Illuminate\Http\Request;
        use Auth;
        // 上記までを追記する
        
        class LoginController extends Controller
        {
            /*
            |--------------------------------------------------------------------------
            | Login Controller
            |--------------------------------------------------------------------------
            |
            | This controller handles authenticating users for the application and
            | redirecting them to your home screen. The controller uses a trait
            | to conveniently provide its functionality to your applications.
            |
            */
        
            use AuthenticatesUsers;
        
            /**
             * Where to redirect users after login.
             *
             * @var string
             */
            protected $redirectTo = '/home';
        
            /**
             * Create a new controller instance.
             *
             * @return void
             */
            public function __construct()
            {
                $this->middleware('guest')->except('logout');
                //下記を追記する
                $this->middleware('guest:admin')->except('logout');
            }
        
            // 下記を追記する
            public function showAdminLoginForm()
            {
                return view('auth.login', ['url' => 'admin']);
            }
        
            public function adminLogin(Request $request)
            {
                $this->validate($request, [
                    'email'   => 'required|email',
                    'password' => 'required|min:6'
                ]);
        
                if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {
        
                    return redirect()->intended('/admin');
                }
                return back()->withInput($request->only('email', 'remember'));
            }
            // 上記までを追記
        }
        ```
    1. 下記コマンドを実行してログインを司るコントローラファイルを開く。

        ```terminal
        $ vi app/Http/Controllers/Auth/RegisterController.php
        ```
    1. 開いたコントローラファイルを下記の様に修正する。

        ```app/Http/Controllers/Auth/RegisterController.php
        <?php
        
        namespace App\Http\Controllers\Auth;
        
        //下記を追記する
        use App\Admin;
        use Illuminate\Http\Request;
        //上記までを追記する
        use App\User;
        use App\Http\Controllers\Controller;
        use Illuminate\Support\Facades\Hash;
        use Illuminate\Support\Facades\Validator;
        use Illuminate\Foundation\Auth\RegistersUsers;
        
        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 = '/home';
        
            /**
             * Create a new controller instance.
             *
             * @return void
             */
            public function __construct()
            {
                $this->middleware('guest');
                //下記を追記する
                $this->middleware('guest:admin');
                //上記までを追記する
            }
        
            /**
             * 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:6|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']),
                ]);
            }
            //下記を追記する
            public function showAdminRegisterForm()
            {
                return view('auth.register', ['url' => 'admin']);
            }
        
            protected function createAdmin(Request $request)
            {
                $this->validator($request->all())->validate();
                $admin = Admin::create([
                    'name' => $request['name'],
                    'email' => $request['email'],
                    'password' => Hash::make($request['password']),
                ]);
                return redirect()->intended('login/admin');
            }
            //上記までを追記する
        }
        ```
1. 管理者ログインページのビューファイルの修正
    1. 下記コマンドを実行してログインページのビューファイルを開く。

        ```terminal
        $ vi resources/views/auth/login.blade.php
        ```
    1. 開いたビューファイルを下記の様に修正する。

        ```resources/views/auth/login.blade.php
        @extends('layouts.app')
        
        @section('content')
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-md-8">
                    <div class="card">
                        <!-- 下記を修正する -->
                        <div class="card-header"> {{ isset($url) ? ucwords($url) : ""}} {{ __('Login') }}</div>
        
                        <div class="card-body">
                            @isset($url)
                            <form method="POST" action='{{ url("login/$url") }}' aria-label="{{ __('Login') }}">
                            @else
                            <form method="POST" action="{{ route('login') }}" aria-label="{{ __('Login') }}">
                            @endisset
                                @csrf
                                <!-- 上記までを修正する -->
        
                                <div class="form-group row">
                                    <label for="email" class="col-sm-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
        
                                    <div class="col-md-6">
                                        <input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required autofocus>
        
                                        @if ($errors->has('email'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $errors->first('email') }}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
        
                                <div class="form-group row">
                                    <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
        
                                    <div class="col-md-6">
                                        <input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
        
                                        @if ($errors->has('password'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $errors->first('password') }}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
        
                                <div class="form-group row">
                                    <div class="col-md-6 offset-md-4">
                                        <div class="form-check">
                                            <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
        
                                            <label class="form-check-label" for="remember">
                                                {{ __('Remember Me') }}
                                            </label>
                                        </div>
                                    </div>
                                </div>
        
                                <div class="form-group row mb-0">
                                    <div class="col-md-8 offset-md-4">
                                        <button type="submit" class="btn btn-primary">
                                            {{ __('Login') }}
                                        </button>
        
                                        <a class="btn btn-link" href="{{ route('password.request') }}">
                                            {{ __('Forgot Your Password?') }}
                                        </a>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        @endsection
        ```
1. 管理者登録ページのビューファイルの修正
    1. 下記コマンドを実行してログインページのビューファイルを開く。

        ```terminal
        $ vi resources/views/auth/register.blade.php
        ```
    1. 開いたビューファイルを下記の様に修正する。

        ```resources/views/auth/register.blade.php
        @extends('layouts.app')
        
        @section('content')
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-md-8">
                    <div class="card">
                        <!-- 下記を修正する -->
                        <div class="card-header"> {{ isset($url) ? ucwords($url) : ""}} {{ __('Register') }}</div>
        
                        <div class="card-body">
                            @isset($url)
                            <form method="POST" action='{{ url("register/$url") }}' aria-label="{{ __('Register') }}">
                            @else
                            <form method="POST" action="{{ route('register') }}" aria-label="{{ __('Register') }}">
                            @endisset
                                @csrf
                                <!-- 上記までを修正する -->
        
                                <div class="form-group row">
                                    <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
        
                                    <div class="col-md-6">
                                        <input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required autofocus>
        
                                        @if ($errors->has('name'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $errors->first('name') }}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
        
                                <div class="form-group row">
                                    <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
        
                                    <div class="col-md-6">
                                        <input id="email" type="email" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email" value="{{ old('email') }}" required>
        
                                        @if ($errors->has('email'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $errors->first('email') }}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
        
                                <div class="form-group row">
                                    <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
        
                                    <div class="col-md-6">
                                        <input id="password" type="password" class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="password" required>
        
                                        @if ($errors->has('password'))
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $errors->first('password') }}</strong>
                                            </span>
                                        @endif
                                    </div>
                                </div>
        
                                <div class="form-group row">
                                    <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
        
                                    <div class="col-md-6">
                                        <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
                                    </div>
                                </div>
        
                                <div class="form-group row mb-0">
                                    <div class="col-md-6 offset-md-4">
                                        <button type="submit" class="btn btn-primary">
                                            {{ __('Register') }}
                                        </button>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        @endsection
        ````
1. 認証後遷移ページの作成
    1. 下記コマンドを実行してビューファイルを作成する。

        ```terminal
        $ touch resources/views/layouts/auth.blade.php
        $ touch resources/views/admin.blade.php
        ````
    1. 下記コマンドを実行して先に作成したビューファイルを開く。

        ```terminal
        $ vi resources/views/layouts/auth.blade.php
        ```
    1. 下記の内容をコピーアンドペーストで貼り付ける。

        ```resources/views/layouts/auth.blade.php
       <!DOCTYPE html>
        <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
    
            <!-- CSRF Token -->
            <meta name="csrf-token" content="{{ csrf_token() }}">
    
            <title>{{ config('app.name', 'Laravel') }}</title>
    
            <!-- Scripts -->
            <script src="{{ asset('js/app.js') }}" defer></script>
    
            <!-- Fonts -->
            <link rel="dns-prefetch" href="https://fonts.gstatic.com">
            <link href="https://fonts.googleapis.com/css?family=Raleway:300,400,600" rel="stylesheet" type="text/css">
    
            <!-- Styles -->
            <link href="{{ asset('css/app.css') }}" rel="stylesheet">
        </head>
        <body>
            <div id="app">
                <nav class="navbar navbar-expand-md navbar-light navbar-laravel">
                    <div class="container">
                        <a class="navbar-brand" href="{{ url('/') }}">
                            {{ config('app.name', 'Laravel') }}
                        </a>
                        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                            <span class="navbar-toggler-icon"></span>
                        </button>
    
                        <div class="collapse navbar-collapse" id="navbarSupportedContent">
                            <!-- Left Side Of Navbar -->
                            <ul class="navbar-nav mr-auto">
    
                            </ul>
    
                            <!-- Right Side Of Navbar -->
                            <ul class="navbar-nav ml-auto">
                                <!-- Authentication Links -->
                               <li class="nav-item dropdown">
                                    <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                        Hi There <span class="caret"></span>
                                    </a>
    
                                    <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                        <a class="dropdown-item" href="{{ route('logout') }}"
                                           onclick="event.preventDefault();
                                                         document.getElementById('logout-form').submit();">
                                            {{ __('Logout') }}
                                        </a>
    
                                        <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                            @csrf
                                        </form>
                                    </div>
                                </li>
                            </ul>
                        </div>
                    </div>
                </nav>
    
                <main class="py-4">
                    @yield('content')
                </main>
            </div>
        </body>
        </html>
        ```
    1. 下記コマンドを実行して先に作成したビューファイルを開く。

        ```terminal
        $ vi resources/views/admin.blade.php
        ```
    1. 下記の内容をコピーアンドペーストで貼り付ける。

        ```resources/views/admin.blade.php
        @extends('layouts.auth')
    
        @section('content')
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-md-8">
                    <div class="card">
                        <div class="card-header">Dashboard</div>
    
                        <div class="card-body">
                            Hi boss!
                        </div>
                    </div>
                </div>
            </div>
        </div>
        @endsection
        ```
    1. 下記コマンドを実行してビューファイルを開く。

        ```terminal
        $ vi resources/views/home.blade.php
        ```
    1. すでに記載されている内容を削除し下記の内容をコピーアンドペーストで貼り付ける。

        ```resources/views/home.blade.php
        @extends('layouts.auth')
    
        @section('content')
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-md-8">
                    <div class="card">
                        <div class="card-header">Dashboard</div>
    
                        <div class="card-body">
                             Hi there, regular user
                        </div>
                    </div>
                </div>
            </div>
        </div>
        @endsection
        ```
1. ルーティングの記載と認証後遷移ページの設定と例外時の処理の記載
    1. 下記コマンドを実行してルーティングファイルを開く。

        ```terminal
        $ vi routes/web.php
        ```
    1. 下記の様に追記する。

        ```routes/web.php 
        <?php
        
        /*
        |--------------------------------------------------------------------------
        | Web Routes
        |--------------------------------------------------------------------------
        |
        | Here is where you can register web routes for your application. These
        | routes are loaded by the RouteServiceProvider within a group which
        | contains the "web" middleware group. Now create something great!
        |
        */
        
        Route::get('/', function () {
            return view('welcome');
        });
        
        Auth::routes();
        
        Route::get('/home', 'HomeController@index')->name('home');
        
        //下記を追記する
        Route::get('/login/admin', 'Auth\LoginController@showAdminLoginForm');
        Route::get('/register/admin', 'Auth\RegisterController@showAdminRegisterForm');
        
        Route::post('/login/admin', 'Auth\LoginController@adminLogin');
        Route::post('/register/admin', 'Auth\RegisterController@createAdmin');
        
        Route::view('/home', 'home')->middleware('auth');
        Route::view('/admin', 'admin');
        //上記までを追記する
        ```
1. リダイレクトの設定
    1. 下記コマンドを実行してリダイレクトを司るミドルウェアファイルを開く

        ```terminal
        $ vi app/Http/Middleware/RedirectIfAuthenticated.php
        ```
    1. 下記の様に追記する。

        ```app/Http/Middleware/RedirectIfAuthenticated.php
        <?php
    
        namespace App\Http\Middleware;
    
        use Closure;
        use Illuminate\Support\Facades\Auth;
    
        class RedirectIfAuthenticated
        {
            public function handle($request, Closure $next, $guard = null)
            {
                // 下記を追記する
                if ($guard == "admin" && Auth::guard($guard)->check()) {
                    return redirect('/admin');
                }
                // 上記までを追記する
                if (Auth::guard($guard)->check()) {
                    return redirect('/home');
                }
    
                return $next($request);
            }
        }
        ```
1. 例外時の設定
    1. 下記コマンドを実行してハンドラーファイルを開く。

        ```terminal
        $ vi app/Exceptions/Handler.php
        ```
    1. 下記のようにハンドラーファイルを修正する。

        ```app/Exceptions/Handler.php
        <?php
        
        namespace App\Exceptions;
        
        use Exception;
        use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
        
        //下記を追記する
        use Illuminate\Auth\AuthenticationException;
        use Auth; 
        //上記までを追記する
        
        class Handler extends ExceptionHandler
        {
            /**
             * A list of the exception types that are not reported.
             *
             * @var array
             */
            protected $dontReport = [
                //
            ];
        
            /**
             * A list of the inputs that are never flashed for validation exceptions.
             *
             * @var array
             */
            protected $dontFlash = [
                'password',
                'password_confirmation',
            ];
        
            /**
             * Report or log an exception.
             *
             * @param  \Exception  $exception
             * @return void
             */
            public function report(Exception $exception)
            {
                parent::report($exception);
            }
        
            /**
             * Render an exception into an HTTP response.
             *
             * @param  \Illuminate\Http\Request  $request
             * @param  \Exception  $exception
             * @return \Illuminate\Http\Response
             */
            public function render($request, Exception $exception)
            {
                return parent::render($request, $exception);
            }
            //下記を追記する
            protected function unauthenticated($request, AuthenticationException $exception)
            {
                if ($request->expectsJson()) {
                    return response()->json(['error' => 'Unauthenticated.'], 401);
                }
                if ($request->is('admin') || $request->is('admin/*')) {
                    return redirect()->guest('/login/admin');
                }
                return redirect()->guest(route('login'));
            }
            //上記までを追記する
        
        }
        ```
1. 確認
    1. 下記コマンドを実行してローカルサーバを起動する。

        ```terminal
        $ php artisan serve
        ```
    1. 下記にアクセスしてLaravelの初期画面が表示されることを確認する。
        - [http://localhost:8000/](http://localhost:8000/)

            ![Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/2c3f4343-8ee0-c775-fa5e-79964bfead6d.png)


    1. 下記にアクセスし必要情報を入力後「Registar」をクリックする。
        - [http://localhost:8000/register/admin](http://localhost:8000/register/admin)

            ![Laravel-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e49f3dd3-fdf8-132d-ccce-abc0b6858408.png)
    
    1. 下記の画面にリダイレクトすることを確認する。管理者登録時の情報を入力し「Login」をクリックする。

        ![Laravel-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/a5cf5f3d-b60c-747c-f298-4751ba04917b.png)

    1. 下記のページ「Hi boss!」が表示されれば管理者としてのログインは完了である。

        ![Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/fe87fe15-bebc-cf3e-3b40-05e33a1bc941.png)


# 参考文献

- [LARAVELアプリで複数の認証ガードを使用する方法](https://pusher.com/tutorials/multiple-authentication-guards-laravel)