Tutorial Bikin RBAC dengan Spatie Permission dan Laravel 11 Projek Website Desa Online

Di era digital seperti sekarang, website desa memiliki peran yang sangat penting dalam mengelola dan mendukung pertumbuhan ekonomi desa. Dengan adanya website desa, semua informasi terkait perkembangan ekonomi, kegiatan masyarakat, layanan publik, serta peluang usaha di desa bisa disebarluaskan secara lebih cepat dan efisien.

Website desa juga berfungsi sebagai jembatan untuk meningkatkan transparansi dan keterlibatan warga dalam pengambilan keputusan di tingkat lokal. Selain itu, website desa dapat menjadi media untuk mempromosikan produk lokal atau pariwisata desa, yang pada akhirnya akan meningkatkan perekonomian desa tersebut.

Fitur Penting dalam Pengelolaan Website Desa

Ada beberapa fitur penting yang harus ada dalam website pengelolaan desa untuk memastikan fungsionalitas dan kemudahan penggunaan. Beberapa fitur tersebut antara lain:

  • Layanan Informasi Publik: Informasi terkait administrasi desa, layanan kependudukan, serta pengumuman resmi dari pemerintah desa.
  • Toko Online: Tempat warga desa memasarkan produk-produk lokal seperti kerajinan tangan, makanan khas, dan sebagainya.
  • Manajemen Acara: Untuk mengelola berbagai acara dan kegiatan yang diadakan di desa, baik acara tradisional, olahraga, maupun kegiatan sosial.
  • Sistem Pengelolaan Pengguna: Pengaturan hak akses berdasarkan peran seperti admin desa, perangkat desa, warga desa, dan pengunjung.
  • Struktur Organisasi: Menampilkan struktur pemerintahan desa dan organisasi terkait lainnya untuk meningkatkan transparansi.

Membangun Website Desa dengan Laravel 11

Laravel 11 adalah pilihan yang tepat untuk membangun website desa karena framework ini menyediakan berbagai fitur yang memudahkan dalam pengembangan website secara cepat, aman, dan scalable.

Dengan fitur-fitur seperti authentication, authorization, dan integrasi yang baik dengan berbagai package, Laravel 11 memungkinkan kita membangun fitur-fitur seperti Role-Based Access Control (RBAC) dengan cepat dan efisien. Salah satu package yang sangat populer untuk menangani RBAC adalah Spatie Permission.

Implementasi Lengkap RBAC dengan Spatie Permission di Laravel 11 untuk Website Desa

Dalam mengimplementasikan Role-Based Access Control (RBAC) dengan Spatie Permission pada proyek website desa, kita akan melalui beberapa tahapan, mulai dari membuat model yang dibutuhkan, menambahkan field-field pada migrations, mengatur relationship antar model, menggunakan factory dan seeder, serta penerapan middleware pada navigasi yang berbeda untuk setiap role dan fitur.

1. Install Laravel dan Spatie Permission

Pertama, kita perlu menginstal Laravel 11 dan package Spatie Permission:

composer require spatie/laravel-permission

Setelah itu, kita jalankan perintah untuk mempublikasi file konfigurasi dan migrasi dari Spatie:

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

2. Membuat Model dan Migrations untuk Proyek

Dalam proyek ini, kita akan membuat beberapa model dan tabel, yaitu users, online_stores, events, roles, dan structure_of_people. Setiap model ini akan memiliki field-field khusus yang disesuaikan dengan kebutuhan website desa.

a. Membuat Model User

Laravel sudah menyediakan model User secara default. Namun, kita perlu menambahkan relasi dengan role dan permission.

// User.php
use Spatie\\\\Permission\\\\Traits\\\\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    public function stores()
    {
        return $this->hasMany(OnlineStore::class);
    }

    public function events()
    {
        return $this->hasMany(Event::class);
    }
}

b. Membuat Model OnlineStore

php artisan make:model OnlineStore -m

Pada migration OnlineStore, kita akan menambahkan field user_id untuk relasi one-to-many antara user dan toko online.

// create_online_stores_table.php
Schema::create('online_stores', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('user_id');
    $table->string('store_name');
    $table->text('description');
    $table->timestamps();

    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

Kemudian di model OnlineStore, kita tambahkan relasi ke model User.

// OnlineStore.php
class OnlineStore extends Model
{
    protected $fillable = ['user_id', 'store_name', 'description'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

c. Membuat Model Event

php artisan make:model Event -m

Pada migration Event, kita tambahkan field user_id untuk relasi one-to-many.

// create_events_table.php
Schema::create('events', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('user_id');
    $table->string('event_name');
    $table->date('event_date');
    $table->timestamps();

    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

Di model Event, tambahkan relasi ke model User.

// Event.php
class Event extends Model
{
    protected $fillable = ['user_id', 'event_name', 'event_date'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

d. Membuat Model StructureOfPeople

php artisan make:model StructureOfPeople -m

Pada migration StructureOfPeople, kita tambahkan field yang relevan.

// create_structure_of_people_table.php
Schema::create('structure_of_people', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('position');
    $table->timestamps();
});

Kemudian di model StructureOfPeople:

// StructureOfPeople.php
class StructureOfPeople extends Model
{
    protected $fillable = ['name', 'position'];
}

3. Mengatur Relationship pada Setiap Model

Setiap model sudah diatur untuk memiliki relasi one-to-many sesuai dengan struktur yang diperlukan di website desa.

  • User memiliki banyak OnlineStore.
  • User memiliki banyak Event.

4. Menggunakan Factory dan Seeder

a. Factory untuk User

Kita bisa membuat factory untuk model User untuk menghasilkan data dummy:

php artisan make:factory UserFactory --model=User

Isi UserFactory dengan contoh data berikut:

// UserFactory.php
public function definition()
{
    return [
        'name' => $this->faker->name(),
        'email' => $this->faker->unique()->safeEmail(),
        'password' => bcrypt('password'),
    ];
}

b. Seeder untuk User, Role, dan Permission

Selanjutnya, kita buat seeder untuk menambahkan data pengguna beserta role dan permission:

php artisan make:seeder RolePermissionSeeder

Isi RolePermissionSeeder sebagai berikut:

// RolePermissionSeeder.php
use Spatie\\\\Permission\\\\Models\\\\Role;
use Spatie\\\\Permission\\\\Models\\\\Permission;

public function run()
{
    // Membuat roles
    Role::create(['name' => 'admin_desa']);
    Role::create(['name' => 'perangkat_desa']);
    Role::create(['name' => 'warga_desa']);
    Role::create(['name' => 'pengunjung']);

    // Membuat permissions
    Permission::create(['name' => 'manage_online_store']);
    Permission::create(['name' => 'manage_events']);
    Permission::create(['name' => 'manage_structure']);

    // Menambahkan role dan permission ke user
    $admin = User::factory()->create();
    $admin->assignRole('admin_desa');
}

Jalankan seeder:

php artisan db:seed --class=RolePermissionSeeder

5. Penerapan Middleware dan Navigasi Berdasarkan Role

Sekarang kita bisa menerapkan middleware untuk membatasi akses berdasarkan role dan permission.

Route::group(['middleware' => ['role:admin_desa']], function() {
    Route::get('/admin/dashboard', [AdminController::class, 'index']);
    Route::get('/admin/stores', [StoreController::class, 'index']);
    Route::get('/admin/events', [EventController::class, 'index']);
});

Route::group(['middleware' => ['role:warga_desa']], function() {
    Route::get('/warga/stores', [StoreController::class, 'manageOwn']);
    Route::get('/warga/events', [EventController::class, 'create']);
});

Dengan middleware ini, hanya admin_desa yang dapat mengakses seluruh toko dan acara, sementara warga_desa hanya dapat mengelola toko dan acara milik mereka sendiri.

5 Kesalahan Umum dalam Implementasi RBAC dengan Spatie Laravel 11

Tidak Memahami Perbedaan antara Roles dan Permissions: Beberapa developer sering menyamakan role dan permission. Padahal, role adalah sekumpulan izin (permissions) yang diberikan kepada pengguna, sementara permission adalah izin spesifik yang mengatur akses ke fitur tertentu. Role dapat berisi beberapa permissions dan dapat diberikan kepada banyak pengguna.

Contoh kode:

// Membuat role dan permission secara terpisah
use Spatie\\\\Permission\\\\Models\\\\Role;
use Spatie\\\\Permission\\\\Models\\\\Permission;

// Membuat role
Role::create(['name' => 'admin_desa']);

// Membuat permission
Permission::create(['name' => 'manage_online_store']);

// Memberikan permission ke role
$role = Role::findByName('admin_desa');
$role->givePermissionTo('manage_online_store');

Mengabaikan Middleware untuk Mengamankan Route: Salah satu kesalahan umum adalah tidak menerapkan middleware yang membatasi akses berdasarkan role atau permission. Middleware ini sangat penting untuk memastikan pengguna hanya dapat mengakses fitur yang sesuai dengan hak akses mereka.

Contoh kode:

Route::group(['middleware' => ['role:admin_desa']], function() {
    Route::get('/admin/dashboard', [AdminController::class, 'index']);
});

Route::group(['middleware' => ['permission:manage_online_store']], function() {
    Route::get('/store/manage', [StoreController::class, 'manage']);
});

Tidak Menggunakan Cache Permissions: Setiap kali aplikasi memeriksa role atau permission, aplikasi melakukan query ke database. Hal ini bisa memperlambat performa jika tidak menggunakan caching. Developer sering lupa untuk mengaktifkan caching yang disediakan oleh Spatie Permission.

Contoh kode untuk mengaktifkan caching:

// Menjalankan command untuk cache role dan permission
php artisan permission:cache-reset

Hardcoding Role dan Permission di Controller: Mengatur role dan permission langsung di controller tanpa menggunakan mekanisme yang lebih fleksibel dapat menyebabkan kesulitan maintenance di masa depan. Sebaiknya, role dan permission dikelola melalui seeder atau command.

Contoh kesalahan:

public function index() {
    if (auth()->user()->role != 'admin_desa') {
        abort(403, 'Akses ditolak');
    }
}

Solusi:

public function index() {
    if (!auth()->user()->hasRole('admin_desa')) {
        abort(403, 'Akses ditolak');
    }
}

Tidak Melakukan Testing pada Fitur RBAC: Banyak developer tidak melakukan pengujian (testing) yang cukup untuk memastikan bahwa fitur RBAC berfungsi dengan baik. Pengujian sangat penting, terutama ketika ada perubahan pada role atau permission, untuk memastikan aplikasi tetap aman.

Contoh kode untuk pengujian:

public function test_admin_can_access_dashboard()
{
    $admin = User::factory()->create();
    $admin->assignRole('admin_desa');

    $response = $this->actingAs($admin)->get('/admin/dashboard');
    $response->assertStatus(200);
}

public function test_non_admin_cannot_access_dashboard()
{
    $user = User::factory()->create();

    $response = $this->actingAs($user)->get('/admin/dashboard');
    $response->assertStatus(403);
}

Dengan menghindari kesalahan-kesalahan ini, developer dapat memastikan implementasi RBAC berjalan dengan baik dan aman.

Belajar Lebih Lanjut dengan Buildwithangga

Jika Anda ingin memperdalam pengetahuan tentang Laravel dan fitur-fitur penting lainnya dalam pengembangan web, Buildwithangga adalah pilihan tepat. Di sini, Anda akan mendapatkan akses ke kursus berkualitas dengan berbagai manfaat yang mendukung perjalanan belajar Anda. Dengan akses seumur hidup, Anda bisa belajar kapan saja tanpa batasan waktu, menjadikan pembelajaran fleksibel sesuai dengan kesibukan Anda.

Selain itu, bonus konsultasi dengan mentor memungkinkan Anda bertanya langsung kepada para ahli, mempercepat pemahaman tentang topik yang sedang dipelajari. Tidak hanya itu, grup diskusi antar siswa memberikan kesempatan untuk berdiskusi, berbagi pengalaman, dan memecahkan masalah secara kolaboratif dengan sesama pelajar.

Persiapan Anda dalam menghadapi dunia kerja juga akan semakin matang dengan dukungan persiapan kerja yang disediakan oleh Buildwithangga. Kursus ini dirancang untuk memberikan keterampilan praktis yang dicari oleh perusahaan, membuat portofolio yang menarik, dan meningkatkan peluang karir Anda sebagai web developer profesional. Dengan pembelajaran yang terstruktur dan materi yang selalu up-to-date, Anda akan lebih siap untuk menghadapi tantangan dan menjadi lebih kompetitif di pasar kerja.

Mulailah perjalanan Anda bersama Buildwithangga, dan buat portofolio proyek nyata yang dapat menunjukkan kemampuan Anda dalam pengembangan web.