Tutorial Laravel #20: Authorization: Gate dan Policy

1. Authentication vs Authorization

Penting dibedakan:

  • Authentication - siapa kamu? (sudah login atau belum)
  • Authorization - kamu boleh apa? (boleh edit artikel ini atau tidak)

Laravel menyediakan dua cara untuk authorization: Gate (untuk aturan sederhana) dan Policy (untuk aturan yang terkait model/resource tertentu).

2. Gate - Aturan Sederhana

<?php
// app/Providers/AppServiceProvider.php
use IlluminateSupportFacadesGate;

public function boot(): void
{
    // Definisikan gate
    Gate::define('akses-admin', function ($user) {
        return $user->role === 'admin';
    });

    Gate::define('edit-artikel', function ($user, $artikel) {
        return $user->id === $artikel->user_id || $user->role === 'admin';
    });
}
// Gunakan di controller
use IlluminateSupportFacadesGate;

public function edit(Artikel $artikel)
{
    // Cara 1: authorize (throw exception jika tidak boleh)
    Gate::authorize('edit-artikel', $artikel);

    // Cara 2: allows/denies (return boolean)
    if (Gate::denies('edit-artikel', $artikel)) {
        abort(403);
    }

    return view('artikel.edit', compact('artikel'));
}
<!-- Gunakan di Blade -->
@can('akses-admin')
    <a href="/admin">Admin Panel</a>
@endcan

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

@cannot('edit-artikel', $artikel)
    <span class="text-muted">Tidak bisa edit</span>
@endcannot

3. Policy - Aturan Berbasis Model

php artisan make:policy ArtikelPolicy --model=Artikel
<?php
// app/Policies/ArtikelPolicy.php
namespace AppPolicies;

use AppModelsArtikel;
use AppModelsUser;

class ArtikelPolicy
{
    // Siapa saja yang boleh lihat daftar
    public function viewAny(User $user): bool
    {
        return true;  // semua user login boleh
    }

    // Siapa yang boleh lihat artikel ini
    public function view(User $user, Artikel $artikel): bool
    {
        return $artikel->status === 'published' || $user->id === $artikel->user_id;
    }

    // Siapa yang boleh buat artikel baru
    public function create(User $user): bool
    {
        return in_array($user->role, ['admin', 'author', 'editor']);
    }

    // Siapa yang boleh update artikel ini
    public function update(User $user, Artikel $artikel): bool
    {
        return $user->id === $artikel->user_id || $user->role === 'admin';
    }

    // Siapa yang boleh hapus artikel ini
    public function delete(User $user, Artikel $artikel): bool
    {
        return $user->id === $artikel->user_id || $user->role === 'admin';
    }
}

4. Mendaftarkan Policy

// app/Providers/AppServiceProvider.php
use AppModelsArtikel;
use AppPoliciesArtikelPolicy;
use IlluminateSupportFacadesGate;

public function boot(): void
{
    Gate::policy(Artikel::class, ArtikelPolicy::class);
    // Atau Laravel bisa auto-discover policy jika naming convention sesuai
}

5. Menggunakan Policy di Controller

public function update(Request $request, Artikel $artikel)
{
    // Gunakan $this->authorize untuk throw 403 jika tidak boleh
    $this->authorize('update', $artikel);

    // Atau
    Gate::authorize('update', $artikel);

    $artikel->update($request->validated());
    return redirect()->route('artikel.index')->with('success', 'Berhasil diperbarui!');
}

public function destroy(Artikel $artikel)
{
    $this->authorize('delete', $artikel);
    $artikel->delete();
    return redirect()->route('artikel.index');
}

6. Super Admin - Bypass Semua Cek

// Di AppServiceProvider
Gate::before(function ($user, $ability) {
    if ($user->role === 'superadmin') {
        return true;  // superadmin lolos semua cek authorization
    }
});

7. Ringkasan

  • Gate untuk aturan authorization sederhana yang tidak terkait model tertentu
  • Policy untuk aturan yang terkait model - lebih terstruktur untuk CRUD
  • Gunakan $this->authorize() di controller atau @can di Blade
  • Gate::before() untuk role superadmin yang bypass semua cek

Tutorial berikutnya membahas relasi Eloquent.


ariq fadhil

Im Ariq Tech, a Top Rated Fullstack Developer with 5+ years of experience, delivering high-quality solutions across 50+ projects.