タイトル: 管理者ユーザーの作成/判定と管理画面
SEOタイトル: Laravel で管理者ユーザーを作る方法 (is_admin / roles / Gate / Middleware
| この記事の要点 |
|
最小実装: is_admin カラム
Laravel で 1 種類しか管理者がいない(一般 / 管理者の 2 値)場合の最速パターン:
// database/migrations/xxxx_add_is_admin_to_users.php
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('is_admin')->default(false)->after('email');
});
}
// User モデル
class User extends Authenticatable
{
protected $casts = [
'is_admin' => 'boolean',
];
public function isAdmin(): bool
{
return (bool) $this->is_admin;
}
}
判定: Gate
// app/Providers/AuthServiceProvider.php
public function boot(): void
{
Gate::define('admin', function (User $user) {
return $user->isAdmin();
});
Gate::define('manage-articles', function (User $user) {
return $user->isAdmin() || $user->hasRole('editor');
});
}
// コントローラで利用
public function destroy(Article $article)
{
Gate::authorize('admin'); // 失敗時 403
$article->delete();
return redirect('/admin/articles');
}
// もしくは
if (Gate::allows('admin')) { ... }
if ($request->user()->can('admin')) { ... }
判定: Blade @can
{{-- resources/views/layouts/app.blade.php --}}
<nav>
<a href="/">トップ</a>
@auth
<a href="/mypage">マイページ</a>
@can('admin')
<a href="/admin">管理画面</a>
@endcan
<form action="/logout" method="post">
@csrf
<button>ログアウト</button>
</form>
@else
<a href="/login">ログイン</a>
@endauth
</nav>
ルート保護: Middleware
php artisan make:middleware AdminMiddleware// app/Http/Middleware/AdminMiddleware.php
public function handle(Request $request, Closure $next): Response
{
if (!$request->user() || !$request->user()->isAdmin()) {
abort(403, '管理者権限が必要です');
}
return $next($request);
}
// app/Http/Kernel.php (Laravel 10 まで)
protected $middlewareAliases = [
'admin' => \App\Http\Middleware\AdminMiddleware::class,
];
// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'admin' => \App\Http\Middleware\AdminMiddleware::class,
]);
})
// routes/web.php
Route::middleware(['auth', 'admin'])->prefix('admin')->group(function () {
Route::get('/', [AdminController::class, 'index']);
Route::resource('users', \App\Http\Controllers\Admin\UserController::class);
});
多役割パターン: roles テーブル
管理者・編集者・閲覧者など複数の役割が必要なら、roles + role_user の多対多にする:
// migration
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name')->unique(); // admin, editor, viewer
$table->string('display_name');
$table->timestamps();
});
Schema::create('role_user', function (Blueprint $table) {
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->foreignId('role_id')->constrained()->cascadeOnDelete();
$table->primary(['user_id', 'role_id']);
});
// User モデル
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class);
}
public function hasRole(string $name): bool
{
return $this->roles->contains('name', $name);
}
public function isAdmin(): bool
{
return $this->hasRole('admin');
}
Spatie Laravel-Permission (推奨)
自前で roles/permissions を作るよりSpatie のパッケージが圧倒的に楽:
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate// User モデル
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable {
use HasRoles;
}
// 役割と権限の作成
$role = Role::create(['name' => 'admin']);
$permission = Permission::create(['name' => 'edit articles']);
$role->givePermissionTo($permission);
// 付与
$user->assignRole('admin');
$user->givePermissionTo('edit articles');
// 判定
$user->hasRole('admin');
$user->can('edit articles');
// Middleware
Route::middleware(['role:admin'])->group(...);
Route::middleware(['permission:edit articles'])->group(...);
管理者アカウントの作成 (Seeder)
// database/seeders/AdminUserSeeder.php
public function run(): void
{
User::firstOrCreate(
['email' => 'admin@example.com'],
[
'name' => 'Admin',
'password' => bcrypt('S3curePassw0rd!'),
'is_admin' => true,
]
);
}
// DatabaseSeeder.php
$this->call(AdminUserSeeder::class);
// 実行
// php artisan db:seed
// 本番では Artisan コマンド経由がおすすめ
管理画面パッケージ比較
| パッケージ | 特徴 | 向いてる用途 |
|---|---|---|
| Filament | Livewire ベース。最新・高機能。Resource 自動生成 | 新規プロジェクト・複雑な管理画面 |
| Laravel Nova | 公式有償。$199/site。安定 | 商用・サポート重視 |
| Backpack | 有償あり。CRUD パネル特化 | シンプルな CRUD 中心 |
| Voyager | 無償。GUI で完結。メンテ停滞気味 | WordPress ライクな感覚 |
| 自前で作る | Bootstrap / Tailwind + Blade | カスタム要件が強い場合 |
Filament を入れる例
composer require filament/filament
php artisan filament:install --panels
php artisan make:filament-user// User モデルに FilamentUser を実装
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;
class User extends Authenticatable implements FilamentUser
{
public function canAccessPanel(Panel $panel): bool
{
return $this->isAdmin();
}
}
FAQ
Q: is_admin と roles どちらを使うべき?
A: ユーザー数少 + 役割 2 種類なら is_admin。役割が増える / 権限が細かいなら Spatie 一択。
Q: 管理画面の URL は隠すべき?
A: /admin 自体は隠しても効果薄。強パスワード + 2FA + IP 制限を組み合わせるのが本筋。
Q: 管理者の操作ログを残したい
A: Spatie laravel-activitylog パッケージで Eloquent モデルの変更を自動記録。