M
Mr Sugiarto
Developer
20 Sep 2026 3 min read

Middleware auth di episode sebelumnya cuma cek "sudah login atau belum" — semua user yang login dianggap setara. Untuk blog sungguhan, biasanya cuma admin yang boleh kelola konten. Episode ini kita bikin role sederhana tanpa package tambahan seperti Spatie Permission — cukup satu kolom boolean dan satu middleware custom.

Screenshot: User yang login tapi bukan admin mendapat 403 Forbidden saat akses /posts/create. User yang login tapi bukan admin mendapat 403 Forbidden saat akses /posts/create.

Migration: tambah kolom is_admin

php artisan make:migration add_is_admin_to_users_table --table=users
public function up(): void
{
    Schema::table('users', function (Blueprint $table) {
        $table->boolean('is_admin')->default(false)->after('password');
    });
}

Update model User

#[Fillable(['name', 'email', 'password', 'is_admin'])]
class User extends Authenticatable
{
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'is_admin' => 'boolean',
        ];
    }
}

'is_admin' => 'boolean' di casts memastikan nilai dari database (0/1) otomatis dikonversi jadi true/false di PHP, bukan integer mentah.

Membuat custom middleware

php artisan make:middleware EnsureUserIsAdmin
class EnsureUserIsAdmin
{
    public function handle(Request $request, Closure $next): Response
    {
        if (! $request->user()?->is_admin) {
            abort(403, 'Only admins can manage posts.');
        }

        return $next($request);
    }
}

Middleware ini menolak request dengan HTTP 403 (Forbidden) kalau user yang login bukan admin.

Mendaftarkan alias middleware

Laravel 11+ (termasuk 13) mendaftarkan middleware lewat bootstrap/app.php, bukan Kernel.php seperti versi lama:

->withMiddleware(function (Middleware $middleware): void {
    $middleware->alias([
        'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
    ]);
})

Menggabungkan dengan middleware auth

Route::middleware(['auth', 'admin'])->group(function () {
    Route::resource('posts', PostController::class)->except(['index', 'show']);
});

Dua middleware ini dijalankan berurutan: auth dulu (pastikan sudah login), baru admin (pastikan yang login itu admin). Kalau salah satu gagal, request langsung ditolak sebelum sampai ke controller.

Update seeder

User::factory()->create([
    'name' => 'Test User',
    'email' => 'test@example.com',
    'is_admin' => true,
]);

Menyembunyikan UI dari non-admin

@auth
    @if (Auth::user()->is_admin)
        <a class="nav-link" href="{{ route('posts.create') }}">New Post</a>
    @endif
@endauth

Testing: admin lolos, user biasa ditolak

# Login sebagai admin, lalu:
curl -b admin-cookies.txt -o /dev/null -w "%{http_code}\n" http://laravel13-blog-dasar.test/posts/create
# -> 200

# Login sebagai user biasa (is_admin: false), lalu:
curl -b user-cookies.txt -o /dev/null -w "%{http_code}\n" http://laravel13-blog-dasar.test/posts/create
# -> 403

Kenapa tidak pakai package permission dari awal?

Untuk kasus sederhana — satu level admin vs user biasa — package seperti Spatie Permission adalah overkill. Kolom boolean + middleware custom sudah cukup, jauh lebih mudah dipahami untuk pemula, dan bisa di-upgrade ke sistem role/permission yang lebih kompleks nanti kalau memang dibutuhkan.

Selanjutnya

Aplikasi sudah fungsional penuh secara lokal. Episode berikutnya kita bahas cara deploy ke VPS sungguhan supaya bisa diakses publik.

M
Mr Sugiarto

Developer

Bagian dari Series: Laravel 13 Dasar — Belajar Fundamental Lewat Blog Sederhana
Lihat Series Lengkap