Hampir setiap aplikasi nyata butuh membedakan siapa boleh melakukan apa: admin bisa menghapus pengguna, editor bisa menulis artikel, member biasa hanya bisa membaca. Membangun sistem ini dari nol itu rumit dan rawan bug. Paket spatie/laravel-permission adalah standar de facto di ekosistem Laravel untuk mengelola role dan permission dengan rapi. Tutorial ini memandu dari instalasi hingga proteksi route.
1. Instalasi Paket
Tambahkan paket lewat Composer, publish konfigurasi dan migration, lalu migrasi:
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate
Migration ini membuat lima tabel: roles, permissions, model_has_roles, model_has_permissions, dan role_has_permissions. Setelah itu bersihkan cache konfigurasi:
php artisan optimize:clear
2. Menambahkan Trait HasRoles ke Model User
Agar model User bisa memiliki role dan permission, tambahkan trait HasRoles:
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
}
Trait ini memberi banyak method praktis seperti assignRole(), hasRole(), givePermissionTo(), dan can(). Semua relasi antara user, role, dan permission disimpan otomatis di tabel pivot yang dibuat saat migrasi, jadi Anda tidak perlu menulis query manual. Konsep intinya sederhana: permission adalah izin terkecil untuk satu aksi, role adalah kumpulan permission yang diberi nama, dan user diberi role sehingga mewarisi semua permission di dalamnya. Memahami hierarki ini akan memudahkan Anda merancang struktur akses yang rapi sejak awal.
3. Membuat Role dan Permission
Anda bisa membuatnya lewat tinker atau, lebih baik, di dalam seeder. Buat permission terlebih dahulu, lalu role:
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);
Permission::create(['name' => 'publish articles']);
$editor = Role::create(['name' => 'editor']);
$admin = Role::create(['name' => 'admin']);
Penting: buat permission dengan nama yang konsisten dan deskriptif (kata kerja + objek), karena nama inilah yang akan Anda cek di seluruh aplikasi.
4. Menetapkan Permission ke Role
Hubungkan permission ke role. Editor boleh menyunting dan menerbitkan; admin mendapat semua permission:
$editor->givePermissionTo(['edit articles', 'publish articles']);
// Admin mendapat semua permission sekaligus
$admin->givePermissionTo(Permission::all());
5. Menetapkan Role ke User
Setelah role siap, tetapkan ke user. Bisa satu atau beberapa role sekaligus:
$user = User::find(1);
$user->assignRole('admin');
// Beberapa role
$user->assignRole(['editor', 'author']);
Karena permission diwarisi dari role, user admin otomatis memiliki semua permission tanpa perlu di-assign satu per satu. Anda juga bisa memberi permission langsung ke user tertentu tanpa lewat role menggunakan givePermissionTo() pada objek user, misalnya untuk memberi satu member akses khusus tanpa mengubah role-nya. Namun sebagai aturan umum, kelola akses lewat role agar lebih mudah dirawat: cukup ubah permission satu role dan semua user dengan role tersebut ikut terpengaruh secara serentak.
6. Mengecek Role dan Permission
Ada beberapa cara memeriksa hak akses. Di controller atau logika PHP:
if ($user->hasRole('admin')) {
// hanya untuk admin
}
if ($user->can('edit articles')) {
// user punya permission ini (langsung atau via role)
}
Di Blade, gunakan direktif @can dan @role untuk menyembunyikan elemen UI:
@can('delete articles')
<button>Hapus</button>
@endcan
@role('admin')
<a href="/admin">Panel Admin</a>
@endrole
7. Memproteksi Route dengan Middleware
Cara paling bersih menjaga akses adalah lewat middleware pada route. Paket ini menyediakan middleware role, permission, dan role_or_permission:
Route::middleware(['auth', 'role:admin'])->group(function () {
Route::resource('users', UserController::class);
});
Route::post('/articles', [ArticleController::class, 'store'])
->middleware('permission:edit articles');
Pada Laravel 11, daftarkan alias middleware di bootstrap/app.php agar bisa dipakai:
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
]);
})
8. Seeding Role agar Konsisten
Jangan buat role secara manual di produksi. Kumpulkan semuanya dalam sebuah seeder agar setiap lingkungan konsisten:
class RolePermissionSeeder extends Seeder
{
public function run(): void
{
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
foreach (['edit articles', 'delete articles', 'publish articles'] as $perm) {
Permission::firstOrCreate(['name' => $perm]);
}
$admin = Role::firstOrCreate(['name' => 'admin']);
$admin->givePermissionTo(Permission::all());
}
}
Gunakan firstOrCreate agar seeder aman dijalankan berulang tanpa membuat duplikat.
Praktik Terbaik
- Cek permission, bukan role, di dalam logika bisnis. Role bisa berubah, tapi kemampuan (permission) lebih stabil.
- Bersihkan cache permission setelah mengubah data dengan
php artisan permission:cache-reset. - Beri satu user sebagai super-admin lewat Gate::before agar selalu lolos semua pengecekan.
Dengan spatie/laravel-permission, sistem otorisasi yang biasanya rumit menjadi ringkas: definisikan permission, kelompokkan dalam role, tetapkan ke user, lalu jaga akses dengan @can dan middleware. Pola ini scalable dari aplikasi kecil hingga sistem besar dengan puluhan peran.
Tips Mengelola Peran dan Izin
Manajemen peran dan izin yang rapi menjaga keamanan sekaligus kemudahan pengelolaan. Rancang peran berdasarkan tanggung jawab nyata di organisasi, misalnya admin, editor, dan pengguna biasa, lalu berikan izin seminimal yang diperlukan untuk masing-masing. Prinsip hak akses paling kecil ini mengurangi risiko bila sebuah akun disalahgunakan. Kelompokkan izin secara logis agar mudah dipelihara ketika fitur bertambah. Hindari memberi izin langsung ke pengguna secara sporadis; lebih baik lewat peran agar konsisten. Sediakan antarmuka bagi admin untuk mengatur peran tanpa harus menyentuh kode. Uji setiap kombinasi peran untuk memastikan tidak ada celah akses yang tidak diinginkan. Terakhir, tinjau peran dan izin secara berkala seiring berkembangnya aplikasi. Dengan struktur yang jelas menggunakan paket seperti Spatie, sistem otorisasi Anda menjadi aman, terukur, dan mudah dikembangkan.