Tutorial Lengkap Laravel Multi Role dengan Spatie + CRUD Role & Permission (Dari Nol Sampai Production Ready)

Tutorial Lengkap Laravel Multi Role dengan Spatie + CRUD Role & Permission (Dari Nol Sampai Production Ready)

Membangun sistem autentikasi saja tidak cukup untuk aplikasi modern. Kamu juga perlu sistem manajemen role dan permission agar setiap user memiliki hak akses yang sesuai. Pada tutorial ini, kamu akan belajar secara lengkap cara membuat multi role system di Laravel menggunakan Spatie, termasuk CRUD Role & Permission, proteksi route, hingga tampilan Blade.

Tutorial ini dibuat sangat lengkap dan terstruktur, sehingga bisa langsung kamu implementasikan ke project nyata.


Persiapan Environment

Sebelum memulai, pastikan kamu sudah memiliki:

  • PHP minimal versi 8.1
  • Composer
  • MySQL atau MariaDB
  • Node.js dan NPM

Cek dengan:

php -v
composer -V
node -v

Instalasi Laravel

Buat project baru:

composer create-project laravel/laravel laravel-multirole

Masuk ke project:

cd laravel-multirole

Jalankan server:

php artisan serve

Setup Database

Edit file .env:

DB_DATABASE=laravel_multirole
DB_USERNAME=root
DB_PASSWORD=

Jalankan migrasi:

php artisan migrate

Instalasi Authentication (Laravel Breeze)

Install Breeze:

composer require laravel/breeze --dev
php artisan breeze:install
npm install && npm run dev
php artisan migrate

Sekarang fitur login sudah tersedia.


Instalasi Spatie Permission

Install package:

composer require spatie/laravel-permission

Publish file:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

Migrasi:

php artisan migrate

Setup Model User

Edit:

use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;
}

Struktur Database Role & Permission

Spatie otomatis membuat tabel:

  • roles
  • permissions
  • model_has_roles
  • role_has_permissions
  • model_has_permissions

Ini adalah fondasi utama sistem multi role.


Membuat Seeder Role dan Permission

Buat seeder:

php artisan make:seeder RolePermissionSeeder

Edit:

use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;

public function run()
{
    $permissions = [
        'role view',
        'role create',
        'role edit',
        'role delete',
    ];

    foreach ($permissions as $perm) {
        Permission::create(['name' => $perm]);
    }

    $admin = Role::create(['name' => 'admin']);
    $admin->givePermissionTo($permissions);

    $user = Role::create(['name' => 'user']);
}

Jalankan:

php artisan db:seed --class=RolePermissionSeeder

Membuat CRUD Role (Full)

Generate Controller

php artisan make:controller RoleController

Route Role

Tambahkan di routes/web.php:

use App\Http\Controllers\RoleController;

Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::resource('roles', RoleController::class);
});

Controller Role (Lengkap)

use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Illuminate\Http\Request;

class RoleController extends Controller
{
    public function index()
    {
        $roles = Role::all();
        return view('roles.index', compact('roles'));
    }

    public function create()
    {
        $permissions = Permission::all();
        return view('roles.create', compact('permissions'));
    }

    public function store(Request $request)
    {
        $role = Role::create(['name' => $request->name]);
        $role->syncPermissions($request->permissions);

        return redirect()->route('roles.index');
    }

    public function edit($id)
    {
        $role = Role::findById($id);
        $permissions = Permission::all();

        return view('roles.edit', compact('role', 'permissions'));
    }

    public function update(Request $request, $id)
    {
        $role = Role::findById($id);
        $role->update(['name' => $request->name]);
        $role->syncPermissions($request->permissions);

        return redirect()->route('roles.index');
    }

    public function destroy($id)
    {
        Role::findById($id)->delete();
        return back();
    }
}

View Role (Blade)

index.blade.php

<a href="{{ route('roles.create') }}">Tambah Role</a>

@foreach($roles as $role)
    <p>{{ $role->name }}</p>
    <a href="{{ route('roles.edit', $role->id) }}">Edit</a>
@endforeach

create.blade.php

<form method="POST" action="{{ route('roles.store') }}">
@csrf

<input type="text" name="name" placeholder="Nama Role">

@foreach($permissions as $perm)
    <label>
        <input type="checkbox" name="permissions[]" value="{{ $perm->name }}">
        {{ $perm->name }}
    </label>
@endforeach

<button type="submit">Simpan</button>
</form>

edit.blade.php

<form method="POST" action="{{ route('roles.update', $role->id) }}">
@csrf
@method('PUT')

<input type="text" name="name" value="{{ $role->name }}">

@foreach($permissions as $perm)
    <label>
        <input type="checkbox" name="permissions[]" value="{{ $perm->name }}"
        {{ $role->hasPermissionTo($perm->name) ? 'checked' : '' }}>
        {{ $perm->name }}
    </label>
@endforeach

<button type="submit">Update</button>
</form>

CRUD Permission

Buat controller:

php artisan make:controller PermissionController

Route:

Route::resource('permissions', PermissionController::class);

Controller:

use Spatie\Permission\Models\Permission;

class PermissionController extends Controller
{
    public function index()
    {
        $permissions = Permission::all();
        return view('permissions.index', compact('permissions'));
    }

    public function create()
    {
        return view('permissions.create');
    }

    public function store(Request $request)
    {
        Permission::create(['name' => $request->name]);
        return redirect()->route('permissions.index');
    }

    public function edit($id)
    {
        $permission = Permission::findById($id);
        return view('permissions.edit', compact('permission'));
    }

    public function update(Request $request, $id)
    {
        $permission = Permission::findById($id);
        $permission->update(['name' => $request->name]);

        return redirect()->route('permissions.index');
    }

    public function destroy($id)
    {
        Permission::findById($id)->delete();
        return back();
    }
}

Assign Role ke User (UI)

Tambahkan di controller User:

$user->syncRoles($request->roles);

Di Blade:

@foreach($roles as $role)
    <input type="checkbox" name="roles[]" value="{{ $role->name }}">
@endforeach

Proteksi Menu di Blade

@role('admin')
    <a href="/roles">Role Management</a>
@endrole

Redirect Berdasarkan Role

Edit LoginController:

if ($user->hasRole('admin')) {
    return redirect('/admin');
}

return redirect('/dashboard');

Testing Sistem

Langkah pengujian:

  1. Login sebagai admin
  2. Tambah role baru
  3. Tambah permission
  4. Assign permission ke role
  5. Assign role ke user
  6. Coba akses route

Best Practice

Agar sistem lebih profesional:

  • Gunakan seeder untuk role default
  • Gunakan middleware di semua route penting
  • Gunakan naming permission yang konsisten
  • Pisahkan role admin dan user dengan jelas

Kesimpulan

Dengan mengikuti tutorial ini, kamu sudah berhasil:

  • Menginstall Laravel dari nol
  • Membuat sistem login
  • Menggunakan Spatie Permission
  • Membuat CRUD Role
  • Membuat CRUD Permission
  • Mengatur akses berdasarkan role
  • Membuat sistem yang scalable

Sistem ini sudah siap digunakan untuk berbagai jenis aplikasi seperti:

  • Sistem admin panel
  • Aplikasi perusahaan
  • Sistem manajemen user

Jika dikembangkan lebih lanjut, kamu bisa membuat:

  • Dashboard dinamis
  • API berbasis role
  • Sistem audit log
  • Multi tenant system

Tutorial ini bisa kamu jadikan fondasi utama untuk project Laravel yang profesional dan production-ready.

Comments

No comments yet. Why don’t you start the discussion?

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *