目的 Auth::user()を使うことなので、ログイン・ログアウト・登録の機能を実装する(管理者・一般ユーザー)
さくっとMulti Authを実装する
Laravel標準装備の認証機能を利用する
php artisan make:auth
管理者のmigrationファイルとModelを作成する。
php artisan make:model Admin -m
app配下にModelsディレクトリを用意し、その下にUser.phpとAdmin.phpを入れる
名前空間をnamespace App\Models;に修正する。
User.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によって、Auth::routes();が作成されているので、これのもとを見てログイン・ログアウト・登録関連のルートをコピーして編集する。
vendor\framework\src\IlluminateRouting\Router.phpのauthメソッドにその記述があるので、参考にする。
$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');
}
上記を参考に
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の中身をコピーして変更
Laravelのmiddlewareはコロン(:)で区切って、引数を指定できる。(今回はadmin)
<?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の中身をコピーして変更する
<?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('/');
}
}
<?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も作成します。ほぼコピーです。(基本的にルートだけ変える)
<!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>
@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
@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
@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にAuth::user()->nameという記述があります。
これは、middlewareの引数でadminを渡しているおかげです。AdminHomeControllerのconstructの記述を引数adminなしにしてみます。
ルートは/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());
}
}
とれています。guardに引数を指定すれば、ログイン中のユーザー情報がとれます。adminと指定すれば、adminのログイン中のユーザーの情報をとれます。