Laravel5.8 認証Multi Auth(マルチログイン)(管理者・一般ユーザー)をお手軽に実装したときに、Auth::user()は管理者・一般ユーザーどっちの値をとるのか気になったので試してみた。

###目的 Auth::user()を使うことなので、ログイン・ログアウト・登録の機能を実装する(管理者・一般ユーザー)

##さくっとMulti Authを実装する

Laravel標準装備の認証機能を利用する

```
php artisan make:auth
```

###管理者のmigrationファイルとModelを作成する。
```
php artisan make:model Admin -m
```

app配下にModelsディレクトリを用意し、その下にUser.phpとAdmin.phpを入れる
名前空間を<b>namespace App\Models;</b>に修正する。

User.phpをAdmin.phpへコピー

```:Admin.php
<?php

namespace App\Models;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    use Notifiable;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

```

もともと用意されているユーザー用のMigrationファイルの中身を管理者用のMigrationファイルへコピー

```
class CreateAdminsTable extends Migration
{
    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }
    
    public function down()
    {
        Schema::dropIfExists('admins');
    }
}
```

テーブルを作成する

```
root@d8801ff1fed8:/var/www# php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Migrating: 2019_06_11_125453_create_admins_table
Migrated:  2019_06_11_125453_create_admins_table
```

###config/auth.php(認証設定)を変更する

```
//デフォルトではguardがwebになっており、webはusersをproviderとしているため、guard・guardsをusers・userに設定しなくてもいいが、見やすさを優先して、今回そうしている。
'defaults' => [
    'guard' => 'user',
    'passwords' => 'users',
],
'guards' => [
    'user' => [
        'driver' => 'session', //認証方法
        'provider' => 'users', //providersの利用するもの
    ],
    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
    ],
],
'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],

    'admins' => [
        'driver' => 'eloquent',             //認証へのアクセス方法
        'model' => App\Models\Admin::class, //参照するテーブル
    ],
],
'passwords' => [
    'users' => [
        'provider' => 'users',
        'table' => 'password_resets',
        'expire' => 60,
    ],
    'admins' => [
        'provider' => 'admins',
        'table' => 'password_resets',  //参照するテーブル
        'expire' => 60,                //パスワードリセットの制限時間(分)
    ],
],
```

設定を変更したので、反映します。

```
php artisan config:cache
```

###route/web.phpを定義する

php artisan make:authによって、<b>Auth::routes();</b>が作成されているので、これのもとを見てログイン・ログアウト・登録関連のルートをコピーして編集する。

vendor\framework\src\IlluminateRouting\Router.phpのauthメソッドにその記述があるので、参考にする。

```:vendor\framework\src\IlluminateRouting\Router.php
$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');
}
```

上記を参考に

```:web.php
Auth::routes();

Route::group(['prefix' => 'admin'], function(){
    Route::get('home', 'AdminHomeController@index')->name('admin_auth.home');
    Route::get('login', 'AdminAuth\LoginController@showLoginForm')->name('admin_auth.login');
    Route::post('login', 'AdminAuth\LoginController@login')->name('admin_auth.login');
    Route::post('logout', 'AdminAuth\LoginController@logout')->name('admin_auth.logout');
    Route::get('register', 'AdminAuth\RegisterController@showRegisterForm')->name('admin_auth.register');
    Route::post('register', 'AdminAuth\RegisterController@register')->name('admin_auth.register');
});

Route::get('/home', 'HomeController@index')->name('home');
```

管理者用(Admin)にルートを作成した。

###コントローラーの作成

先ほど作成したルートを元に作成していく。

HomeController.phpの中身をコピーして変更
<b>Laravelのmiddlewareはコロン(:)で区切って、引数を指定できる。(今回はadmin)


```:AdminHomeController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;

class AdminHomeController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:admin');
    }
    
    public function index()
    {
        return view('admin_home');
    }
}
```

Controllersディレクトリ配下にAuthAdminディレクトリを作成して、AuthのLoginController.phpとRegisterController.phpの中身をコピーして変更する

```:AdminAuth\LoginController
<?php

namespace App\Http\Controllers\AdminAuth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = '/admin/home';

    public function __construct()
    {
        $this->middleware('guest:admin')->except('logout');
    }

    public function showLoginForm()
    {
        return view('admin_auth.login');
    }

    protected function guard()
    {
        return Auth::guard('admin');
    }

    public function logout(Request $request)
    {
        $this->guard()->logout();
        return redirect('/');
    }
}
```

```:AdminAuth\ResisterController
<?php

namespace App\Http\Controllers\AdminAuth;

use App\Models\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

class RegisterController extends Controller
{
    use RegistersUsers;
    
    protected $redirectTo = '/admin/home';
    
    public function __construct()
    {
        $this->middleware('guest:admin');
    }

    public function showRegisterForm()
    {
        return view('admin_auth.register');
    }
    
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:admins',
            'password' => 'required|string|min:6|confirmed',
        ]);
    }

    protected function create(array $data)
    {
        return Admin::create([
            'name' => $data['name'], 
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }

    protected function guard()
    {
        return Auth::guard('admin');
    }

}

```

###Viewを用意する

今回は、ユーザーは一通りそろっているので、管理者用にログインと登録画面を用意します。

views配下にadmin_authディレクトリを作成して、その下にauthディレクトリの中の、login.blade.phpとresister.blade.phpを、コピーして変更する。また、layout配下にadmin_app.blade.phpを作成し、views配下にadmin_home.blade.phpも作成します。ほぼコピーです。(基本的にルートだけ変える)

```layouts/admin_app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <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="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
    <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
        <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 -->
                    @guest
                        <li class="nav-item">
                            <a class="nav-link" href="{{ route('admin.login') }}">{{ __('Login') }}</a>
                        </li>
                        @if (Route::has('register'))
                            <li class="nav-item">
                                <a class="nav-link" href="{{ route('admin.register') }}">{{ __('Register') }}</a>
                            </li>
                        @endif
                    @else
                        <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>
                                {{ Auth::user()->name }} <span class="caret"></span>
                            </a>

                            <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                <a class="dropdown-item" href="{{ route('admin.logout') }}"
                                   onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                    {{ __('Logout') }}
                                </a>

                                <form id="logout-form" action="{{ route('admin.logout') }}" method="POST" style="display: none;">
                                    @csrf
                                </form>
                            </div>
                        </li>
                    @endguest
                </ul>
            </div>
        </div>
    </nav>

    <main class="py-4">
        @yield('content')
    </main>
</div>
</body>
</html>

```

```:admin_auth/login.blade.php
@extends('layouts.admin_app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('admin.login') }}">
                        @csrf

                        <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 @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </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 @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </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>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
```

```:admin_auth/resister.blade.php
@extends('layouts.admin_app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Register') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('admin.register') }}">
                        @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 @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>

                                @error('name')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </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 @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </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 @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </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 autocomplete="new-password">
                            </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
```

```:admin_home.blade.php
@extends('layouts.admin_app')

@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">
                        @if (session('status'))
                            <div class="alert alert-success" role="alert">
                                {{ session('status') }}
                            </div>
                        @endif

                        Admin logged in!
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

```

とりあえず完成

##Auth::user()は何をとるのか
app.blade.phpとadmin_app.blade.phpに<b>Auth::user()->name</b>という記述があります。

<img width="729" alt="Screenshot_3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325600/69458773-37ab-e6e0-6797-dceaa3e60ee2.png">
<img width="753" alt="Screenshot_4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325600/320d1ccf-51eb-6460-39d0-f453d30b8142.png">
写真を見ると、それぞれのnameがちゃんと取れています。

<b>これは、middlewareの引数でadminを渡しているおかげです。</b>AdminHomeControllerのconstructの記述を引数adminなしにしてみます。
<img width="734" alt="Screenshot_5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325600/4520a73d-962d-113c-712a-4e885f5247a0.png">
ルートは/admin/homeなのに、Auth::user()->nameは、useruserになっています。

###もし、middleware(auth)を通さず、Auth::user()的なことを取得したい時(引数で分けたい)(管理者・一般ユーザー)

今回試すために、AdminHomeControllerのindexを利用します。ここで、userの情報を取ってみます。

```
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;

class AdminHomeController extends Controller
{
    public function __construct()
    {

    }

    public function index()
    {
        dd(Auth::guard('user')->user());
    }
}
```

<img width="313" alt="Screenshot_6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325600/667b6d7c-74d5-a6c0-0226-4cde0e13c094.png">
とれています。guardに引数を指定すれば、ログイン中のユーザー情報がとれます。adminと指定すれば、adminのログイン中のユーザーの情報をとれます。