Kembali ke Artikel
10 November 2025
vandyahmad24
Diperbarui: 18 April 2026

Contoh Implementasi Policy dan Gate di Laravel 12: Studi Kasus CMS Multi-Role

Artikel ini melanjutkan penjelasan konsep Policy dan Gate di Laravel 12 dengan studi kasus implementasi lengkap: sistem manajemen konten dengan beberapa level akses.

Studi Kasus: Sistem CMS dengan Multi-Role

Skenario: aplikasi CMS dengan role admin, editor, dan author. Aturannya:

  • Admin bisa lakukan semua aksi di artikel mana saja
  • Editor bisa buat, edit, dan publish artikel mana saja
  • Author hanya bisa buat dan edit artikel miliknya sendiri

Setup Model User dengan Role

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    protected $fillable = ['name', 'email', 'password', 'role'];

    public function isAdmin(): bool
    {
        return $this->role === 'admin';
    }

    public function isEditor(): bool
    {
        return in_array($this->role, ['admin', 'editor']);
    }
}

ArticlePolicy Lengkap

<?php

namespace App\Policies;

use App\Models\Article;
use App\Models\User;

class ArticlePolicy
{
    // Ini dijalankan sebelum semua method lain
    // Return true = admin bypass semua check
    public function before(User $user, string $ability): ?bool
    {
        if ($user->isAdmin()) {
            return true;
        }

        return null; // null = lanjut ke check berikutnya
    }

    public function viewAny(?User $user): bool
    {
        // Semua orang bisa lihat daftar artikel yang published
        return true;
    }

    public function view(?User $user, Article $article): bool
    {
        if ($article->status === 'published') {
            return true;
        }

        // Draft hanya bisa dilihat pemilik atau editor
        return $user && ($article->user_id === $user->id || $user->isEditor());
    }

    public function create(User $user): bool
    {
        return $user->hasVerifiedEmail();
    }

    public function update(User $user, Article $article): bool
    {
        // Editor bisa edit semua, author hanya punya sendiri
        return $user->isEditor() || $article->user_id === $user->id;
    }

    public function delete(User $user, Article $article): bool
    {
        // Hanya admin (via before()) atau pemilik artikel
        return $article->user_id === $user->id;
    }

    public function publish(User $user, Article $article): bool
    {
        // Hanya editor ke atas yang bisa publish
        return $user->isEditor();
    }

    public function restore(User $user, Article $article): bool
    {
        return $user->isEditor() || $article->user_id === $user->id;
    }
}

Menggunakan Policy di Controller

<?php

namespace App\Http\Controllers;

use App\Models\Article;
use App\Http\Requests\StoreArticleRequest;

class ArticleController extends Controller
{
    public function index()
    {
        $this->authorize('viewAny', Article::class);

        $articles = Article::with('author')
                           ->when(!auth()->user()?->isEditor(), fn ($q) =>
                               $q->where('status', 'published')
                                 ->orWhere('user_id', auth()->id())
                           )
                           ->paginate(15);

        return view('articles.index', compact('articles'));
    }

    public function edit(Article $article)
    {
        $this->authorize('update', $article);
        return view('articles.edit', compact('article'));
    }

    public function destroy(Article $article)
    {
        $this->authorize('delete', $article);
        $article->delete();
        return redirect()->route('articles.index')
                         ->with('success', 'Artikel dihapus.');
    }

    public function publish(Article $article)
    {
        $this->authorize('publish', $article);
        $article->update(['status' => 'published', 'published_at' => now()]);
        return back()->with('success', 'Artikel dipublish.');
    }
}

Policy di Blade Template

@foreach ($articles as $article)
    <div>
        <h2>{{ $article->title }}</h2>

        @can('update', $article)
            <a href="{{ route('articles.edit', $article) }}">Edit</a>
        @endcan

        @can('publish', $article)
            @if($article->status === 'draft')
                <form action="{{ route('articles.publish', $article) }}" method="POST">
                    @csrf @method('PATCH')
                    <button>Publish</button>
                </form>
            @endif
        @endcan

        @can('delete', $article)
            <form action="{{ route('articles.destroy', $article) }}" method="POST">
                @csrf @method('DELETE')
                <button>Hapus</button>
            </form>
        @endcan
    </div>
@endforeach

Gate untuk Aksi Global

Untuk akses fitur yang tidak terkait model tertentu, pakai Gate:

// Di AppServiceProvider
Gate::define('access-analytics', fn (User $user) => $user->isEditor());
Gate::define('export-all-data',  fn (User $user) => $user->isAdmin());
// Di controller
Gate::authorize('access-analytics');
return view('analytics.dashboard');

// Di Blade
@can('access-analytics')
    <a href="/analytics">Analytics</a>
@endcan

Baca Juga

Butuh tim yang bantu implementasi sistem otorisasi yang tepat untuk aplikasi Laravel Anda? Lihat layanan pengembangan aplikasi kami.

Tag: #laravel #php #tutorial
BACA JUGA

Artikel Lainnya di Kategori Laravel

Laravel

10 November 2025

Apa Itu Observer di Laravel 12 dan Kapan Menggunakannya

Kalau Event dan Listener cocok untuk “sesuatu terjadi di aplikasi, beri tahu komponen lain”, Observer punya fokus berbeda: “ketika Eloquent model berubah, jalankan kode ini.” Artikel ini menjelaskan apa itu Observer di Laravel 12, perbedaannya dengan Event Listener, dan kapan sebaiknya dipakai. Apa Itu Observer? Observer adalah kelas yang merespons event lifecycle Eloquent model: saat […]

Baca Artikel
Laravel

10 November 2025

Contoh Penggunaan Concurrency di Laravel 12: Dashboard, API Paralel, dan Defer

Artikel sebelumnya membahas konsep Concurrency di Laravel 12. Artikel ini fokus pada implementasi: studi kasus nyata bagaimana Concurrency bisa mempercepat aplikasi secara signifikan. Studi Kasus 1: Dashboard dengan Banyak Data Source Dashboard admin yang butuh data dari beberapa tabel berbeda. Ini biasanya jadi bottleneck karena diquery satu per satu. Sebelum (sequential — sekitar 800ms): public […]

Baca Artikel
Laravel

10 November 2025

Apa Itu Policy dan Gate di Laravel 12: Sistem Otorisasi yang Tepat

Bayangkan ada dua pertanyaan berbeda soal keamanan di aplikasi Anda: “Apakah user ini boleh edit artikel?” dan “Apakah user yang login adalah editor?” Pertanyaan pertama terkait Policy: otorisasi berdasarkan resource. Pertanyaan kedua terkait Gate: otorisasi berdasarkan kemampuan/role. Keduanya bagian dari sistem Authorization di Laravel. Apa Itu Gate? Gate adalah cara mendefinisikan otorisasi berbasis kemampuan (ability) […]

Baca Artikel

Ingin Membaca Artikel Lainnya?

Temukan lebih banyak insight dan tips tentang teknologi dan bisnis digital.

Lihat Semua Artikel