====== 【Laravel 7】マルチ認証(User と Admin で階層分け) ======
参考:[[https://qiita.com/namizatork/items/5d56d96d4c255a0e3a87|Laravel6でマルチ認証を実装する(UserとAdminの階層を分ける)]]
===== パッケージのインストール =====
composer require laravel/ui:^2.4
php artisan ui vue --auth
# vue.js を使わない場合は、以下の手順は不要
# NodeJS がない場合はインストール
curl -sL https://rpm.nodesource.com/setup_14.x | bash -
yum -y install nodejs
# package.json に記載されたパッケージのインストール
npm install
# css、js ファイルのビルド(未圧縮)
npm run dev
# css、js ファイルのビルド(圧縮)
npm run production
===== マイグレーション =====
以下コマンドで、マイグレーションファイルとモデルファイルを作成。
# Model ファイル作成 (-m オプションでマイグレーションも作成)
php artisan make:model Models/Admin -m
database\migrations に作成された「create_admins_table.php」に「create_users_table.php」の中身をコピペし、admin 用に書き換える。
* クラス名:CreateUsersTable → CreateAdminsTable
* テーブル名:users → admins
# マイグレーションの実行
php artisan migrate
===== モデル =====
app 直下にある User.php を app\Models の中に 移動。
// ディレクトリを移動したので、namespace を書き換え
namespace App;
↓
namespace App\Models;
// app\Models\User.php の内容をコピペし、クラス名を書き換える
class User extends Authenticatable
↓
class Admin extends Authenticatable
モデルファイルのパスが変わったので、関係するファイルも書き換え。
use App\User;
↓
use App\Models\User;
'model' => App\User::class,
↓
'model' => App\Models\User::class,
===== シーダー =====
ログイン用のアカウントを作成する。
# シーダー作成
php artisan make:seeder UsersTableSeeder
php artisan make:seeder AdminsTableSeeder
// 追加
use App\Models\User;
public function run()
{
// 本番環境以外でのみアカウントを追加
if (config('app.env') !== 'production') {
$user = User::where('email', 'user@example.com')->first();
if (is_null($user)) {
$user = new User();
$user->name = 'user';
$user->email = 'user@example.com';
$user->password = bcrypt('user');
$user->save();
}
}
}
// 追加
use App\Models\Admin;
public function run()
{
// 本番環境以外でのみアカウントを追加
if (config('app.env') !== 'production') {
$admin = Admin::where('email', 'admin@example.com')->first();
if (is_null($admin)) {
$admin = new Admin();
$admin->name = 'admin';
$admin->email = 'admin@example.com';
$admin->password = bcrypt('admin');
$admin->save();
}
}
}
public function run()
{
// 追加
$this->call([
AdminsTableSeeder::class,
UsersTableSeeder::class,
]);
}
# シーダーをオートローダに登録
php composer dump-autoload
# シーディング実行
php artisan db:seed
===== コンフィグ =====
認証の設定ファイルをマルチ認証対応に書き換える。
// デフォルトを user に変更
'defaults' => [
'guard' => 'user',
'passwords' => 'users',
],
'guards' => [
// web → user に変更
'user' => [
'driver' => 'session',
'provider' => 'users',
],
// admin を追加
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// admins を追加
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
// admins を追加
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
===== コントローラー =====
app\Http\Controllers に User ディレクトリを作成し、Auth ディレクトリと HomeController.php をその中に移動。\\
今回、ログイン機能しか使わないため Auth 内のファイルは LoginController.php 以外を削除。
// namespace を書き換え
namespace App\Http\Controllers\User;
// 追加
use App\Http\Controllers\Controller;
public function __construct()
{
// 今回ルーティング側で auth 設定をしているため
// コンストラクタでは何もしない
// コントローラ側で auth を設定したい場合は以下のようにする
// $this->middleware('auth:user');
}
public function index()
{
// 書き換え
return view('user.home');
}
// namespace の書き換え
namespace App\Http\Controllers\User\Auth;
// 追加
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
public function __construct()
{
// 書き換え
$this->middleware('guest:user')->except('logout');
}
// 以下追加
protected function guard()
{
return Auth::guard('user');
}
public function showLoginForm()
{
return view('user.auth.login');
}
public function logout(Request $request)
{
Auth::guard('user')->logout();
return $this->loggedOut($request);
}
public function loggedOut(Request $request)
{
return redirect(route('user.login'));
}
app\Http\Controllers\User ディレクトリをコピーして Admin ディレクトリを作成。\\
ディレクトリ内の各ファイルに、以下の置換を行う。
* User → Admin
* user → admin
※ AuthenticatesUsers を AuthenticatesAdmins に置換しないように注意
==== ログイン後のリダイレクト先を Admin 用に書き換える ====
protected $redirectTo = RouteServiceProvider::ADMIN_HOME;
===== ルーティング =====
Route::namespace('User')->prefix('user')->name('user.')->group(function(){
Auth::routes([
'register' => false,
'reset' => false,
'verify' => false
]);
Route::middleware('auth:user')->group(function(){
Route::get('home', 'HomeController@index')->name('home');
});
});
Route::namespace('Admin')->prefix('admin')->name('admin.')->group(function(){
Auth::routes([
'register' => false,
'reset' => false,
'verify' => false
]);
Route::middleware('auth:admin')->group(function(){
Route::get('home', 'HomeController@index')->name('home');
});
});
===== その他書き換え =====
// 書き換え
public const HOME = '/user/home';
// 追加
public const ADMIN_HOME = '/admin/home';
// 追加
use Illuminate\Support\Facades\Route;
protected function redirectTo($request)
{
// 書き換え
if (! $request->expectsJson()) {
if (Route::is('user.*')) {
return route('user.login');
} elseif (Route::is('admin.*')) {
return route('admin.login');
}
}
}
public function handle($request, Closure $next, $guard = null)
{
// 書き換え
if (Auth::guard($guard)->check() && $guard === 'user') {
return redirect(RouteServiceProvider::HOME);
} elseif (Auth::guard($guard)->check() && $guard === 'admin') {
return redirect(RouteServiceProvider::ADMIN_HOME);
}
return $next($request);
}
// 追加
use Illuminate\Session\TokenMismatchException;
public function render($request, Throwable $exception)
{
// 追加
// 419 csrf トークン切れで戻る
if ($exception instanceof TokenMismatchException) {
return back()->withErrors(['time_out' => 'セッションがタイムアウトしました']);
}
return parent::render($request, $exception);
}
===== ビュー =====
views\layouts にある app.blade.php を app_user.blade.php などにリネーム。
// リンク先などを必要に応じて変更
route('login')
↓
route('user.login')
route('logout')
↓
route('user.logout')
app_user.blade.php をコピーして app_admin.blade.php を作成。\\
リンク先を route('admin.login') など admin 用に変更。
resources\views 直下に user ディレクトリ作成し、auth ディレクトリと home.blade.php を移動。\\
home.blade.php で extends しているファイルを変更。
// 書き換え
@extends('layouts.app_user')
auth ディレクトリ内にある login.blade.php 以外を削除する。
// 書き換え
@extends('layouts.app_user')
// リンク先を変更
route('login')
↓
route('user.login')
resources\views\user をコピーして admin ディレクトリを作成。\\
admin ディレクトリ内の各ファイルについて、以下の置換を行う。
* user → admin
一通り作業が完了したので、user、admin それぞれの URL にアクセスしてログイン画面が表示されることを確認。\\
https://example.com/user/home\\
https://example.com/admin/home