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

Contoh Penggunaan Contract di Laravel 12: Implementasi dan Binding

Kalau Anda sudah membaca artikel tentang apa itu Contract di Laravel 12, artikel ini melanjutkannya dengan contoh penggunaan nyata: bagaimana membuat implementasi Contract sendiri dan kapan ini berguna dalam proyek. Menggunakan Contract Bawaan Laravel Contract bawaan Laravel ada di namespace Illuminate\Contracts\*. Contoh yang paling sering dipakai adalah type-hinting di constructor untuk decoupling: <?php namespace App\Services; […]

Baca Artikel
Laravel

9 November 2025

Tutorial PostgreSQL di Laravel: Setup, JSONB, dan Full-Text Search

Laravel secara default menggunakan MySQL. Tapi kalau proyek Anda butuh fitur seperti JSON columns yang lebih canggih, full-text search bawaan, atau JSONB, PostgreSQL adalah pilihan yang solid. Artikel ini membahas cara setup PostgreSQL di Laravel, termasuk konfigurasi, perbedaan dengan MySQL, dan fitur-fitur PostgreSQL yang bisa dimanfaatkan langsung dari Eloquent. Instalasi dan Konfigurasi Pastikan extension PHP […]

Baca Artikel
laravel Laravel

9 November 2025

Membuat Controller di Laravel 12: Resource, API, dan Best Practice

Controller adalah salah satu komponen paling sering ditulis di Laravel. Hampir setiap fitur butuh controller: dari menampilkan halaman, menyimpan data form, sampai mengembalikan JSON untuk API. Artikel ini membahas cara membuat controller di Laravel 12: dari controller dasar, resource controller, sampai best practice yang dipakai tim profesional. Membuat Controller Baru Gunakan perintah Artisan: php artisan […]

Baca Artikel

Ingin Membaca Artikel Lainnya?

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

Lihat Semua Artikel