はじめに
今回初めてqiitaを書くため、読みにくい点が多いかと思いますがご容赦ください。
laravel5.5を使用しており、最新のバージョンではありません。
MultiAuth(マルチログイン)とは
MultiAuth(マルチログイン)は、『ユーザと管理者の2つに分けてログインが行える機能である』という想定をしています。
アプリを使用するゲストユーザ → user
アプリを管理する管理者 → admin
前提
- laravelの環境構築を終えている
- MAMPを使用
- DBとの接続を終えている
- 管理者側はログインのみの実装(管理者は1人と想定しSeederでデータを入れる)
- ゲストユーザは新規登録、ログインが行える
実装手順
1.ゲストユーザ側の認証機能の実装
2.モデルのディレクトリを変更
3.管理者側のモデル作成
4.管理者側のモデル編集
5.管理者側のマイグレーションファイル編集
6.管理者側のログイン情報をseedで作成
7.管理者側のコントローラー編集
8.管理者側のビュー画面作成
9.管理者側のビュー画面編集
10.認証ファイルの編集
11.ルーティングの設定
1. ゲストユーザ側の認証機能の実装
laravelのバージョンによってコマンドが異なります。
//Larvel5.8まで
$php artisan make:auth
//Laravel6.x 以降
$composer require laravel/ui --dev
$php artisan ui bootstrap --auth
特にカラムなどの変更がなければ、続けて以下のコマンドを打ちます。
$php artisan migrate
この作業だけで、ゲストユーザ側はログイン、ログアウト、新規登録が行えます。
2. モデルのディレクトリを変更
モデルを作成する際は、Modelsディレクトリで管理したいと思います。
ファイルの修正が必要になってくるのですが、簡潔に分かりやすく説明してくださっている
以下のqiitaを参考にしてみてください。
参考: 【Laravel】モデルのディレクトリ構成変更についてのメモ
ここまで作業ができたら、
$php artisan serve
でサーバーを立ち上げます。
新規登録、ログイン、ログアウトが問題なく出来ているか確認してみましょう。
3. 管理者側のモデル作成
以下のコマンドを打ちます。
-mをつけることでマイグレーションファイルも一緒に生成してくれます。
$php artisan make:model Models/Admin -m
Models/Admin.php(モデル)
と
create_admins_table.php ファイル(マイグレーション)
が生成されるはずです。
4. 管理者側のモデル編集
Models/User.phpの中身をコピーしてModels/Admin.phpに貼り付けます。
Userの部分をAdminに変更しましょう。
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
+ class Admin extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'email', 'password', //今回はnameを登録しないので'name'を削除してます
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
5. 管理者側のマイグレーションファイル編集
今回はemailとpasswordからログインを行うため、必要なカラムを追記します。
* xxxxは作成した日付などの数字が入ります。
<?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('email')->unique();
+ $table->string('password');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('admins');
}
}
6. 管理者側のログイン情報をseedで作成
まずは、以下のコマンドでSeederを作成しましょう.
$php artisan make:seeder AdminsTableSeeder
seedsディレクトリの中にAdminsTableSeeder.php
が作成されますので、編集していきましょう。
emailやpasswordは何でも構いませんので自由に決めてください。
⚠️emailのドメインはなるべくexample.com
を使用した方が良いです。
理由が気になる方はググってみてください!
<?php
use Illuminate\Database\Seeder;
class AdminsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
+ DB::table('admins')->insert([
+ 'email' => 'test@example.com',
+ 'password' => Hash::make('000000'),
+ ]);
}
}
DatabaseSeeder.php
に以下を追記します。
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
+ $this->call(AdminsTableSeeder::class);
}
}
編集が終わったら、dbに反映させましょう。
$php artisan migrate --seed
MAMPを起動させphpMyAdminを開き、
以下のようにadminsテーブルに情報が入っているか確認してみましょう。
7. 管理者側のコントローラー編集
ターミナルでapp/Http/Controllers/に移動しAdminディレクトリを作成します。
右クリックでフォルダを作成でも構いません。
$cd app/Http/Controllers/
$mkdir Admin
Adminディレクトリの中に
LoginController.php
とHomeController.php
を作成します。
⚠️自分のいるディレクトリが正しいか確認してからコマンドを打ちましょう。
(Controllers/配下にいるとコマンドが打てません!)
$php artisan make:controller Admin/LoginController
$php artisan make:controller Admin/HomeController
Adminディレクトリの中に作成されているか確認しましょう。
Admin/LoginController
から編集していきます。
既存のAuth/LoginController
をコピーして貼り付けた後、変更していきます。
<?php
+ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
+ 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 loginForm()
+ {
+ return view('admin.login');
+ }
+ protected function guard()
+ {
+ return Auth::guard('admin');
+ }
}
続いてAdmin/HomeController
を
既存のHomeController
を参照しながら追記していきます。
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class HomeController extends Controller
{
public function __construct()
{
+ $this->middleware('auth:admin');
}
public function index()
{
+ return view('admin.home');
}
}
8. 管理者側のビュー画面作成
ターミナルでresources/views/に移動しadminディレクトリを作成します。
右クリックでフォルダを作成でも構いません。
$cd resources/views/
$mkdir admin
adminディレクトリの中に
login.blade.php
とhome.blade.php
を作成します。
$cd admin
$touch login.blade.php
$touch home.blade.php
adminディレクトリの中に作成されているか確認しましょう。
admin/login.blade.php
から編集していきます。
既存のauth/login.blade.php
をコピーして貼り付けた後、2箇所の変更をしていきます。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
- <div class="panel-heading">Login</div>
+ <div class="panel-heading">Admin Login</div>
<div class="panel-body">
- <form class="form-horizontal" method="POST" action="{{ route('login') }}">
+ <form class="form-horizontal" method="POST" action="{{ route('admin.login') }}">
{{ csrf_field() }}
...省略
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
admin/home.blade.php
も編集していきます。
既存のhome.blade.php
をコピーして貼り付けた後、1箇所だけ変更をしていきます。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Dashboard</div>
<div class="panel-body">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
- You are logged in!
+ You are logged in admin!
</div>
</div>
</div>
</div>
</div>
@endsection
9. 管理者側のビュー画面編集
続いてwelcome.blade.php
を編集していきます。
@auth
ではなく@if
に変更しています。
Auth::guard('admin')->check()
を使用し、
管理者かゲストユーザかどちらのログインであるかを判断しそれぞれのhomeに飛ばすように設定しました。
ログインをしていない場合は新規登録、それぞれのログインを表示します。
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
...省略
</head>
<body>
<div class="flex-center position-ref full-height">
@if (Route::has('login'))
<div class="top-right links">
+ @if (Auth::guard('admin')->check())
+ <a href="{{ route('admin.home') }}">Home</a>
+ @elseif (Auth::guard('user')->check())
+ <a href="{{ route('home') }}">Home</a>
+ @else
+ <a href="{{ route('login') }}">Login</a>
+ <a href="{{ route('register') }}">Register</a>
+ <a href="{{ route('admin.login') }}">Admin Login</a>
+ @endif
</div>
@endif
<div class="content">
...省略
</div>
</div>
</body>
</html>
次にapp.blade.php
を編集していきます。
@guest
はログインをしているかどうかで表示を分けています。
今回、管理者にはnameカラムを実装していません。
そのため、if文で管理者であればemailを表示するように、
ゲストユーザであればnameを表示するように書き換えました。
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
...省略
</head>
<body>
<div id="app">
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
...省略
</div>
<div class="collapse navbar-collapse" id="app-navbar-collapse">
<!-- Left Side Of Navbar -->
<ul class="nav navbar-nav">
</ul>
<!-- Right Side Of Navbar -->
<ul class="nav navbar-nav navbar-right">
<!-- Authentication Links -->
@guest
<li><a href="{{ route('login') }}">Login</a></li>
<li><a href="{{ route('register') }}">Register</a></li>
+ <li><a href="{{ route('admin.login') }}">Admin Login</a></li>
@else
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" v-pre>
+ @if (Auth::guard('admin')->check())
+ {{ Auth::user()->email }}
+ @else
+ {{ Auth::user()->name }}
+ @endif
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
...省略
</ul>
</li>
@endguest
</ul>
</div>
</div>
</nav>
@yield('content')
</div>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
10. 認証ファイルの編集
どんなログイン方法にするか、どのデータベースの情報を見にいくかの設定をしています。
<?php
return [
'defaults' => [
- 'guard' => 'web',
+ 'guard' => 'user',
'passwords' => 'users',
],
'guards' => [
- 'web' => [
+ 'user' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
+ 'admin' => [
+ 'driver' => 'session',
+ 'provider' => 'admins',
+ ],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
- 'model' => App\User::class,
+ 'model' => App\Models\User::class,
],
+ 'admins' => [
+ 'driver' => 'eloquent',
+ 'model' => App\Models\Admin::class,
+ ],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
+ 'admins' => [
+ 'provider' => 'admins',
+ 'table' => 'password_resets',
+ 'expire' => 60,
+ ],
],
];
11. ルーティングの設定
Auth::routes()
は、authの認証のルーティングを用意してくれています。(ありがたいですね)
アプリ内の以下のフォルダに記述されています。
vendor/laravel/framework/src/Illuminate/Routing/Router.php
今回、ゲストユーザはこちらを使用します。
prefix('admin')
とすることでurlの最初に/admin
がつきます。
ログインであれば/admin/login
となります。
middleware('auth')
はログインしているときのみ、表示ができるようになります。
middleware('auth:user')
だと、ゲストユーザとしてログインしている時
middleware('auth:admin')
だと、管理者としてログインしている時
<?php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index')
->middleware('auth:user')
->name('home');
Route::prefix('admin')
->group(function () {
Route::get('/login', 'Admin\LoginController@loginForm')->name('admin.login');
Route::post('/login', 'Admin\LoginController@login');
});
Route::prefix('admin')
->middleware('auth:admin')
->group(function () {
Route::get('/home', 'Admin\HomeController@index')->name('admin.home');
});
最後に
うまく反映されない場合はキャッシュをクリアすることをお勧めします。
//アプリケーションのキャッシュクリア
$php artisan cache:clear
//configのキャッシュクリア
$php artisan config:clear
//ルーティング系のキャッシュクリア
$php artisan route:clear
参考文献
この記事は以下の情報を参考にして執筆しました。