【Laravel 認証機能】Adminユーザの作成 4. 管理者ログイン機能 & 管理者ページの作成
目次
Laravel 認証機能 – 管理者ログイン機能 & 管理者ページの作成
ここからは、これまで準備してきたデータベース設定、ガード&ミドルウェアの仕組みを利用して、ログイン機能の管理者用ユーザ対応と、管理者ユーザ専用ページを実装していきます。
これまでの内容
【Laravel11 認証機能】Adminユーザの作成 1. データベース管理設定
【Laravel11 認証機能】Adminユーザの作成 2. ガード・プロバイダ設定 &ミドルウェア作成
環境: Laravel 11, PHP 8.3.14
要件・仕様
本記事で実装する管理者用機能の要件及び、仕様は以下です。
認証
- 管理者ユーザのログインには、通常ユーザと共通のログイン画面(
/login
)を使用します。 - ログイン処理では、管理者ユーザを優先して認証し、認証に成功した場合は管理者専用ページ(
/admin
)へ遷移させます。 - 管理者ユーザと通常ユーザのいずれか一方のみがログイン可能とし、同一ブラウザでの同時ログインを禁止します。
- 管理者ユーザのログインには、通常ユーザと共通のログイン画面(
アクセス制御
- 管理者ユーザがログイン中に以下の挙動を実現します:
- TOPページ(
/
):- 通常ユーザ向けのダッシュボードリンクの代わりに、管理者専用ページ(
/admin
)へのリンクを表示します。
- 通常ユーザ向けのダッシュボードリンクの代わりに、管理者専用ページ(
- ダッシュボードページ(
/dashboard
)へのアクセス:- 管理者ユーザが通常ユーザ用のダッシュボードページのURLにアクセスした場合、トップページ(
/
)にリダイレクトします。
- 管理者ユーザが通常ユーザ用のダッシュボードページのURLにアクセスした場合、トップページ(
- ログイン画面(
/login
)へのアクセス:- ログイン中のユーザは通常ユーザと同様、トップページ(
/
)にリダイレクトします。
- ログイン中のユーザは通常ユーザと同様、トップページ(
- プロフィールページ(
/profile
):- 通常ユーザ、管理者ユーザどちらかでログイン中のみプロフィールページ(
/profile
)を閲覧可能です。
- 通常ユーザ、管理者ユーザどちらかでログイン中のみプロフィールページ(
- TOPページ(
視覚的な区別
- 管理者ユーザログイン時には、画面に通常ユーザとは異なる背景色やスタイルを適用し、視覚的に管理者用ページであることを明確にします。
実装
ログイン用コントローラの変更
ログイン用のコントローラクラスのログイン処理に管理者用のログイン認証を追加します。
app/Http/Controllers/Auth/LoginController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/**
* ログインフォームを表示する
*
* @return \Illuminate\View\View
*/
public function showLoginForm()
{
return view('auth.login');
}
/**
* ユーザーのログイン処理を実行する
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function login(Request $request)
{
// 1. リクエストのデータを検証する
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
// 2. 管理者ユーザーとしての認証を試みる
if (Auth::guard('admin')->attempt($credentials, $request->filled('remember'))) {
$request->session()->regenerate();
// 認証成功: 管理者ページにリダイレクト
return redirect()->intended(route('admin.index'));
}
// 3. 一般ユーザーとしての認証を試みる
if (Auth::attempt($credentials, $request->filled('remember'))) {
// 認証成功: 一般ダッシュボードにリダイレクト
$request->session()->regenerate();
return redirect()->intended('dashboard');
}
// 4. 認証に失敗した場合
return back()->withErrors([
'email' => 'ログイン情報が正しくありません。',
])->onlyInput('email');
}
}
ページレイアウトの変更
前ページ共通のレイアウト用ビューファイルを修正し、管理者用ユーザログイン時のみ特別なスタイルが適用されるようにします。
resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title', 'Laravel App')</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f8f9fa;
}
body.admin {
background-color: #f0f7ff;
}
.container {
max-width: 500px;
padding: 20px;
background-color: #ffffff;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.admin .container {
background-color: #ffffff;
box-shadow: 0 0 15px rgba(13, 110, 253, 0.2);
}
.form-label {
font-weight: bold;
}
</style>
</head>
<body class="{{ Auth::guard('admin')->check() ? 'admin' : '' }}">
<div class="container">
@yield('content')
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
トップページの変更
トップページ内に管理者用ガードの認証状態をチェックする条件分岐を加えます。
管理者用ユーザでログインしていればユーザ名と、管理者用ページへのリンクを表示します。
resources/views/index.blade.php
@extends('layouts.app')
@section('title', 'トップページ')
@section('content')
<h2 class="text-center mb-4">トップページ</h2>
@if(Auth::guard('admin')->check())
<p class="text-center">管理者としてログイン中: {{ Auth::guard('admin')->user()->name }}</p>
<div class="d-flex justify-content-center">
<a href="{{ route('admin.index') }}" class="btn btn-primary mx-2">管理者ページ</a>
</div>
@elseif(Auth::check())
<p class="text-center">ログイン中: {{ Auth::user()->name }}</p>
<div class="d-flex justify-content-center">
<a href="{{ route('dashboard') }}" class="btn btn-primary mx-2">ダッシュボード</a>
</div>
@else
<div class="d-flex justify-content-center">
<a href="{{ route('register') }}" class="btn btn-outline-primary mx-2">ユーザー登録</a>
<a href="{{ route('login') }}" class="btn btn-outline-primary mx-2">ログイン</a>
</div>
@endif
@endsection
管理者用ページ作成
管理者専用ページのテンプレートを作成します。
resources/views/admin/index.blade.php
@extends('layouts.app')
@section('title', '管理者専用ページ')
@section('content')
<h2 class="text-center mb-4">管理者専用ページ</h2>
<div class="d-flex justify-content-center">
<a href="{{ route('home') }}" class="btn btn-outline-secondary mx-2">トップページに戻る</a>
</div>
<form class="text-center mt-4" action="{{ route('logout') }}" method="POST" class="d-inline">
@csrf
<button type="submit" class="btn btn-danger mx-2">ログアウト</button>
</form>
@endsection
認証済み共通ページ: プロフィール
通常ユーザ、管理者用ページ共通でログイン時に閲覧できるプロフィールページを作成します。
resources/views/profile.blade.php
@extends('layouts.app')
@section('title', 'プロフィール')
@section('content')
<h2 class="text-center mb-4">プロフィール</h2>
@if (Auth::guard('admin')->check() || Auth::check())
<p class="text-center">ユーザ名: {{ Auth::guard('admin')->user()->name ?? Auth::user()->name }}</p>
<p class="text-center">メールアドレス: {{ Auth::guard('admin')->user()->email ?? Auth::user()->email }}</p>
@endif
@endsection
ルーティングの作成・変更
ルーティングファイルに管理者用ページのURLと新しく追加したミドルウェアの設定を行います。
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\Auth\LoginController;
use App\Http\Controllers\Auth\LogoutController;
// トップページのルート
Route::get('/', [HomeController::class, 'index'])->name('home');
// ダッシュボードのルート(通常ユーザでのログインが必要)
Route::get('/dashboard', [HomeController::class, 'dashboard'])
->middleware('auth')
->name('dashboard');
// ユーザー登録のルート
Route::get('register', [RegisterController::class, 'showRegistrationForm'])
->name('register')
->middleware('custom.guest');
Route::post('register', [RegisterController::class, 'register']);
// ログインのルート
Route::get('login', [LoginController::class, 'showLoginForm'])
->middleware('custom.guest')
->name('login');
Route::post('login', [LoginController::class, 'login']);
// ログアウトのルート
Route::post('logout', [LogoutController::class, 'logout'])
->name('logout');
// 管理者用のルート
Route::prefix('admin')->group(function () {
Route::get('/', function () {
return view('admin.index');
})
->name('admin.index')
->middleware('admin');
});
// プロフィール(ログイン中のみ閲覧可)
Route::middleware('authenticated')->group(function () {
Route::get('profile', function () {
return view('profile');
});
});
ログイン画面(/login
)へのミドルウェアをcustom.guestに変更。
管理者用ページへのリクエストはadminミドルウェアでadminガードの認証で保護します。
(現在は管理者ページのみですが、Route::prefix
でグルーピングしています)
新たに作成したプロフィールページ(/profille
)はミドルウェアauthenticated
にて、デフォルト & adminの両ガード共通で保護します。
まとめ
複数回に渡り、Laravel11の認証機能に自作で管理者ユーザ機能を追加する方法を解説してきました。
今回の仕様では管理者ページ自体に特別な内容を含みませんでしたが、今後作成するアプリケーションの要件に応じて、ここまで作成してきた認証やアクセス制限の仕組みを土台にして、機能追加等カスタマイズを行なうことが出来ますので、是非参考にしてみてください。