Tutorial Middleware Laravel dan Spatie Role Permission Projek Web Doctor Appointment

Pada tutorial kali ini, kita akan membahas bagaimana menerapkan custom middleware menggunakan Laravel 11 dan library Spatie Role Permission dalam sebuah proyek website Doctor Appointment. Middleware adalah salah satu fitur penting dalam Laravel yang memungkinkan kita untuk mengatur logika akses pada aplikasi secara fleksibel dan terstruktur.

Dalam proyek ini, middleware akan digunakan untuk mengatur akses berdasarkan peran pengguna, seperti pasien, dokter, atau admin, yang dikelola menggunakan Spatie Role Permission.

Middleware memberikan kemampuan untuk memeriksa dan memproses permintaan pengguna sebelum mencapai controller. Dengan pendekatan ini, Anda dapat menjaga keamanan aplikasi dan memastikan setiap pengguna hanya memiliki akses ke fitur yang relevan dengan perannya.

Manfaat Membuat Custom Middleware dalam Proyek Doctor Appointment

  1. Keamanan Lebih Terjamin Custom middleware memungkinkan Anda untuk memastikan setiap pengguna hanya dapat mengakses halaman atau fitur sesuai dengan hak aksesnya. Misalnya, pasien hanya dapat melihat jadwal dokter dan membuat janji temu, sementara dokter hanya dapat melihat jadwal pasien. Dengan middleware, semua logika keamanan ini dapat diterapkan di satu tempat, sehingga meminimalkan celah akses yang tidak diinginkan.
  2. Kode Lebih Tersusun dan Mudah Dikelola Dengan middleware, Anda dapat memisahkan logika otorisasi dari controller. Ini membuat kode lebih bersih dan terorganisir. Sebagai contoh, Anda tidak perlu menulis logika pengecekan peran di setiap metode controller; cukup gunakan middleware untuk menangani hal tersebut, sehingga controller hanya fokus pada logika bisnis aplikasi.
  3. Skalabilitas dan Fleksibilitas Tinggi Ketika aplikasi berkembang, custom middleware memberikan fleksibilitas untuk menambahkan logika baru tanpa mengubah banyak kode yang ada. Misalnya, jika nanti Anda menambahkan peran baru seperti "admin klinik," Anda cukup memperbarui middleware tanpa harus memodifikasi controller atau rute satu per satu.

Apa Itu Spatie dan Bagaimana Mempermudah Developer Mengembangkan Website dengan Custom Middleware?

Spatie adalah sebuah library populer di Laravel yang menyediakan paket-paket open-source untuk berbagai kebutuhan pengembangan aplikasi web. Salah satu paket paling sering digunakan adalah Spatie Laravel Permission, yang dirancang untuk membantu developer mengelola peran (roles) dan izin (permissions) dengan mudah.

Paket ini memungkinkan pengaturan akses berbasis peran dengan cara yang terstruktur dan fleksibel, sehingga sangat cocok untuk aplikasi yang memerlukan sistem otorisasi kompleks, seperti proyek website Doctor Appointment.

Kemudahan yang Ditawarkan Spatie

  1. Pengelolaan Roles dan Permissions yang Mudah Spatie memungkinkan developer mendefinisikan peran (seperti dokter, pasien, atau admin) dan izin (seperti mengelola jadwal atau membuat janji temu) secara langsung melalui database atau file konfigurasi. Dengan pendekatan ini, pengaturan otorisasi menjadi lebih dinamis karena bisa diubah tanpa harus memodifikasi kode program secara langsung.
  2. Integrasi yang Lancar dengan Middleware Laravel Spatie bekerja sangat baik dengan fitur middleware di Laravel. Anda dapat menggunakan middleware bawaan yang disediakan oleh Spatie atau membuat custom middleware untuk menerapkan logika otorisasi spesifik. Misalnya, Anda dapat memastikan hanya dokter yang memiliki izin tertentu yang bisa mengakses fitur pengelolaan pasien.
  3. Dokumentasi yang Komprehensif Spatie menyediakan dokumentasi lengkap yang membantu developer memahami cara mengimplementasikan sistem roles dan permissions. Ini mempermudah developer pemula maupun berpengalaman untuk mengintegrasikan fitur tersebut tanpa banyak hambatan.
  4. Mengurangi Kompleksitas Logika Otorisasi Tanpa Spatie, developer sering kali harus menulis logika otorisasi secara manual untuk setiap controller atau rute. Dengan Spatie, tugas ini menjadi jauh lebih sederhana karena fungsi-fungsi otorisasi sudah tersedia dan dapat digunakan dengan mudah melalui middleware atau helper yang disediakan.
  5. Skalabilitas yang Baik Spatie dirancang untuk mendukung aplikasi yang terus berkembang. Anda dapat menambahkan atau memodifikasi peran dan izin tanpa memengaruhi bagian lain dari aplikasi. Ini memberikan fleksibilitas tinggi, terutama pada aplikasi yang memiliki banyak pengguna dengan kebutuhan akses berbeda-beda.

Berikut adalah langkah-langkah untuk membuat proyek Laravel 11 dan mengatur MySQL pada file .env secara lengkap.

1. Membuat Proyek Laravel 11

Pastikan Anda sudah menginstal Composer di komputer. Buka terminal atau command prompt, lalu jalankan perintah berikut untuk membuat proyek Laravel 11:

composer create-project --prefer-dist laravel/laravel doctor-appointment "11.*"

Perintah ini akan membuat folder proyek bernama doctor-appointment dan menginstal Laravel versi 11 di dalamnya.

2. Masuk ke Direktori Proyek

Setelah proyek selesai diinstal, masuk ke direktori proyek dengan perintah berikut:

cd doctor-appointment

3. Menyiapkan Database MySQL

Buka aplikasi database Anda (misalnya phpMyAdmin, MySQL Workbench, atau terminal MySQL), lalu buat database baru untuk proyek ini. Misalnya, nama database adalah doctor_appointment.

4. Mengatur Koneksi Database pada File .env

Buka file .env yang ada di folder root proyek. Cari bagian pengaturan database dan ubah sesuai dengan konfigurasi MySQL Anda:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=doctor_appointment
DB_USERNAME=root
DB_PASSWORD=your_password

Penjelasan:

  • DB_CONNECTION: Tetapkan koneksi database ke MySQL.
  • DB_HOST: Masukkan alamat host server MySQL (default: 127.0.0.1).
  • DB_PORT: Masukkan port MySQL (default: 3306).
  • DB_DATABASE: Nama database yang telah Anda buat.
  • DB_USERNAME: Username untuk koneksi MySQL (default: root).
  • DB_PASSWORD: Password untuk username MySQL Anda.

5. Menguji Koneksi Database

Untuk memastikan konfigurasi berhasil, jalankan perintah berikut di terminal:

php artisan migrate

Perintah ini akan menjalankan migrasi bawaan Laravel untuk membuat tabel default seperti users, password_resets, dan lainnya di database. Jika tidak ada error, maka koneksi database sudah berhasil diatur.

6. Menjalankan Proyek Laravel

Setelah pengaturan selesai, jalankan server development Laravel dengan perintah:

php artisan serve

Laravel akan menjalankan server pada http://127.0.0.1:8000 atau alamat lain yang ditampilkan di terminal. Anda dapat membuka alamat tersebut di browser untuk melihat halaman default Laravel.

Berikut adalah langkah-langkah lengkap untuk membuat file migration dengan tabel doctors, categories, hospitals, dan booking_transactions di Laravel 11.

1. Membuat File Migration

Buka terminal di dalam folder proyek Laravel Anda, lalu jalankan perintah berikut untuk membuat migration:

php artisan make:migration create_doctors_table
php artisan make:migration create_categories_table
php artisan make:migration create_hospitals_table
php artisan make:migration create_booking_transactions_table

Perintah di atas akan membuat empat file migration di folder database/migrations.

2. Mengedit Migration untuk Tabel doctors

Buka file migration dengan nama mirip create_doctors_table.php di folder database/migrations, lalu tambahkan struktur tabel seperti berikut:

public function up()
{
    Schema::create('doctors', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('specialization');
        $table->string('phone')->nullable();
        $table->unsignedBigInteger('hospital_id');
        $table->timestamps();

        $table->foreign('hospital_id')->references('id')->on('hospitals')->onDelete('cascade');
    });
}

3. Mengedit Migration untuk Tabel categories

Buka file migration dengan nama mirip create_categories_table.php, lalu tambahkan struktur tabel berikut:

public function up()
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description')->nullable();
        $table->timestamps();
    });
}

4. Mengedit Migration untuk Tabel hospitals

Buka file migration dengan nama mirip create_hospitals_table.php, lalu tambahkan struktur tabel berikut:

public function up()
{
    Schema::create('hospitals', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('address');
        $table->string('phone')->nullable();
        $table->timestamps();
    });
}

5. Mengedit Migration untuk Tabel booking_transactions

Buka file migration dengan nama mirip create_booking_transactions_table.php, lalu tambahkan struktur tabel berikut:

public function up()
{
    Schema::create('booking_transactions', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('doctor_id');
        $table->unsignedBigInteger('patient_id');
        $table->date('booking_date');
        $table->time('booking_time');
        $table->string('status')->default('pending');
        $table->timestamps();

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

6. Menjalankan Migration

Setelah selesai mengedit semua file migration, jalankan perintah berikut untuk membuat tabel di database:

php artisan migrate

Jika tidak ada error, tabel-tabel doctors, categories, hospitals, dan booking_transactions akan berhasil dibuat di database.

Tata Cara Membuat Model di Laravel 11 dan Mengatur Fillable serta Relationship ORM

Laravel 11 menyediakan Eloquent ORM yang mempermudah pengelolaan data dalam aplikasi. Dalam artikel ini, kita akan membuat file model untuk tabel doctors, categories, hospitals, dan booking_transactions.

Selain itu, kita juga akan mengatur properti fillable dan relasi antar model menggunakan ORM. Fokusnya adalah bagaimana middleware Laravel 11 dapat bekerja bersama model ini untuk menjaga otorisasi data secara optimal.

Membuat File Model dan Mengatur Fillable

Langkah pertama adalah membuat model untuk setiap tabel. Gunakan perintah berikut di terminal:

php artisan make:model Doctor
php artisan make:model Category
php artisan make:model Hospital
php artisan make:model BookingTransaction

Perintah ini akan membuat file model di folder app/Models.

Selanjutnya, buka masing-masing file model dan tambahkan properti fillable untuk menentukan kolom mana yang dapat diisi secara massal.

Model Doctor

Buka file app/Models/Doctor.php dan tambahkan kode berikut:

<?php

namespace App\\Models;

use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Database\\Eloquent\\Model;

class Doctor extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'specialization',
        'phone',
        'hospital_id',
    ];

    public function hospital()
    {
        return $this->belongsTo(Hospital::class);
    }

    public function bookings()
    {
        return $this->hasMany(BookingTransaction::class);
    }
}

Model Category

Buka file app/Models/Category.php dan tambahkan kode berikut:

<?php

namespace App\\Models;

use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Database\\Eloquent\\Model;

class Category extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'description',
    ];
}

Model Hospital

Buka file app/Models/Hospital.php dan tambahkan kode berikut:

<?php

namespace App\\Models;

use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Database\\Eloquent\\Model;

class Hospital extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'address',
        'phone',
    ];

    public function doctors()
    {
        return $this->hasMany(Doctor::class);
    }
}

Model BookingTransaction

Buka file app/Models/BookingTransaction.php dan tambahkan kode berikut:

<?php

namespace App\\Models;

use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Database\\Eloquent\\Model;

class BookingTransaction extends Model
{
    use HasFactory;

    protected $fillable = [
        'doctor_id',
        'patient_id',
        'booking_date',
        'booking_time',
        'status',
    ];

    public function doctor()
    {
        return $this->belongsTo(Doctor::class);
    }

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

Mengatur Relationship ORM

  • Doctor memiliki relasi belongsTo dengan Hospital karena setiap dokter berafiliasi dengan satu rumah sakit.
  • Doctor juga memiliki relasi hasMany dengan BookingTransaction karena dokter dapat memiliki banyak transaksi janji temu.
  • Hospital memiliki relasi hasMany dengan Doctor karena satu rumah sakit dapat memiliki banyak dokter.
  • BookingTransaction memiliki relasi belongsTo dengan Doctor dan User (sebagai pasien).

Install Package Spatie

Berikut adalah langkah-langkah untuk menginstal dan mengatur package Spatie Role Permission di proyek Laravel 11 Anda. Package ini membantu mengelola peran dan izin dengan mudah menggunakan Eloquent ORM.

1. Menginstal Package Spatie

Buka terminal di direktori proyek Anda, lalu jalankan perintah berikut untuk menginstal package:

composer require spatie/laravel-permission

Package ini akan diunduh dan ditambahkan ke proyek Anda.

2. Memublikasikan File Konfigurasi dan Migration

Setelah package berhasil diinstal, jalankan perintah berikut untuk memublikasikan file konfigurasi dan migration:

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

Perintah ini akan membuat file konfigurasi config/permission.php dan migration yang diperlukan untuk tabel roles, permissions, dan lainnya.

3. Menjalankan Migration

Untuk membuat tabel yang diperlukan oleh package Spatie di database, jalankan perintah berikut:

php artisan migrate

Tabel seperti roles, permissions, dan model_has_roles akan dibuat.

4. Mengatur Model User untuk Menggunakan Trait Spatie

Buka file app/Models/User.php dan tambahkan trait HasRoles yang disediakan oleh Spatie:

<?php

namespace App\\Models;

use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
use Illuminate\\Foundation\\Auth\\User as Authenticatable;
use Illuminate\\Notifications\\Notifiable;
use Spatie\\Permission\\Traits\\HasRoles;

class User extends Authenticatable
{
    use HasFactory, Notifiable, HasRoles;

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

Trait HasRoles memungkinkan model User menggunakan metode untuk mengatur peran dan izin.

5. Menambahkan Middleware Spatie ke Kernel Laravel

Buka file app/Http/Kernel.php dan tambahkan middleware Spatie di dalam grup $routeMiddleware:

protected $routeMiddleware = [
    // Middleware lainnya
    'role' => \\Spatie\\Permission\\Middlewares\\RoleMiddleware::class,
    'permission' => \\Spatie\\Permission\\Middlewares\\PermissionMiddleware::class,
    'role_or_permission' => \\Spatie\\Permission\\Middlewares\\RoleOrPermissionMiddleware::class,
];

Middleware ini memungkinkan Anda membatasi akses ke rute berdasarkan peran atau izin.

6. Menambahkan Role dan Permission di Seeder (Opsional)

Jika Anda ingin menambahkan peran dan izin secara otomatis, buat file seeder dengan perintah:

php artisan make:seeder RolePermissionSeeder

Lalu edit file seeder tersebut (misalnya di database/seeders/RolePermissionSeeder.php) seperti berikut:

<?php

namespace Database\\Seeders;

use Illuminate\\Database\\Seeder;
use Spatie\\Permission\\Models\\Role;
use Spatie\\Permission\\Models\\Permission;

class RolePermissionSeeder extends Seeder
{
    public function run()
    {
        // Membuat peran
        $admin = Role::create(['name' => 'admin']);
        $doctor = Role::create(['name' => 'doctor']);
        $patient = Role::create(['name' => 'patient']);

        // Membuat izin
        Permission::create(['name' => 'manage appointments']);
        Permission::create(['name' => 'view appointments']);

        // Memberikan izin ke peran
        $admin->givePermissionTo(['manage appointments', 'view appointments']);
        $doctor->givePermissionTo(['view appointments']);
    }
}

Jalankan seeder dengan perintah berikut:

php artisan db:seed --class=RolePermissionSeeder

MEngatur Routing Pada Route

1. Membuka File Routing

Buka file routes/web.php di proyek Laravel Anda. Di file ini, Anda akan menentukan rute untuk setiap role atau permission.

2. Menambahkan Rute Khusus Berdasarkan Role

Gunakan middleware role untuk membatasi akses ke rute berdasarkan role pengguna. Berikut adalah contoh implementasinya:

use Illuminate\\Support\\Facades\\Route;

Route::middleware(['role:admin'])->group(function () {
    Route::get('/admin/dashboard', function () {
        return view('admin.dashboard');
    })->name('admin.dashboard');

    Route::get('/admin/users', function () {
        return view('admin.users');
    })->name('admin.users');
});

Rute ini hanya dapat diakses oleh pengguna dengan peran admin.

3. Menambahkan Rute Khusus Berdasarkan Permission

Gunakan middleware permission untuk membatasi akses ke rute berdasarkan permission pengguna:

Route::middleware(['permission:manage appointments'])->group(function () {
    Route::get('/appointments/manage', function () {
        return view('appointments.manage');
    })->name('appointments.manage');
});

Rute ini hanya dapat diakses oleh pengguna yang memiliki izin manage appointments.

4. Menambahkan Rute untuk Role Lainnya (Contoh: Doctor dan Patient)

Anda dapat membuat grup rute tambahan untuk role seperti doctor dan patient:

Route::middleware(['role:doctor'])->group(function () {
    Route::get('/doctor/dashboard', function () {
        return view('doctor.dashboard');
    })->name('doctor.dashboard');

    Route::get('/doctor/appointments', function () {
        return view('doctor.appointments');
    })->name('doctor.appointments');
});

Route::middleware(['role:patient'])->group(function () {
    Route::get('/patient/dashboard', function () {
        return view('patient.dashboard');
    })->name('patient.dashboard');

    Route::get('/patient/appointments', function () {
        return view('patient.appointments');
    })->name('patient.appointments');
});

5. Membuat Rute untuk Role atau Permission Kombinasi

Jika ingin membatasi akses berdasarkan kombinasi role atau permission, gunakan middleware role_or_permission:

Route::middleware(['role_or_permission:admin|view appointments'])->group(function () {
    Route::get('/shared/dashboard', function () {
        return view('shared.dashboard');
    })->name('shared.dashboard');
});

Rute ini dapat diakses oleh pengguna dengan role admin atau yang memiliki izin view appointments.

6. Menambahkan Fallback Rute untuk Akses Ditolak

Jika pengguna mencoba mengakses rute tanpa izin, Anda dapat mengatur fallback dengan middleware bawaan Laravel:

Route::fallback(function () {
    return response()->view('errors.403', [], 403);
});

Dengan fallback ini, jika pengguna tidak memiliki akses, mereka akan diarahkan ke halaman error 403.

Penjelasan Tambahan

  • Middleware role, permission, dan role_or_permission digunakan untuk membatasi akses berdasarkan role dan izin.
  • Pastikan Anda telah membuat view seperti admin.dashboard, doctor.dashboard, dan lainnya agar rute dapat berfungsi tanpa error.
  • Gunakan nama rute (name()) untuk mempermudah pengelolaan rute dalam aplikasi.

Dengan pengaturan ini, setiap rute diatur secara terstruktur berdasarkan role dan permission, menjaga keamanan dan fleksibilitas aplikasi Anda.

Beberapa kesalahan utama pas mengatur routing middleware

1. Salah Menentukan Middleware atau Typo dalam Middleware

Kesalahan ini terjadi ketika middleware ditulis dengan nama yang salah atau tidak terdaftar dalam Kernel.php. Misalnya:

Route::middleware(['roles:admin'])->group(function () { // Salah: middleware yang benar adalah 'role'
    Route::get('/admin/dashboard', function () {
        return view('admin.dashboard');
    });
});

Penyebab: Middleware roles tidak ada dalam daftar middleware Laravel. Middleware yang benar dari Spatie adalah role.

Cara Memperbaiki:

Route::middleware(['role:admin'])->group(function () { // Benar: middleware yang sesuai dengan Spatie
    Route::get('/admin/dashboard', function () {
        return view('admin.dashboard');
    });
});

Pastikan middleware yang digunakan sudah sesuai dengan dokumentasi Spatie dan terdaftar dalam file Kernel.php.

2. Tidak Menambahkan Middleware di Kernel.php

Kesalahan ini terjadi ketika middleware yang dibutuhkan tidak ditambahkan ke dalam $routeMiddleware di Kernel.php. Misalnya, Anda mencoba menggunakan middleware role tanpa mendaftarkannya:

Route::middleware(['role:admin'])->group(function () {
    Route::get('/admin/dashboard', function () {
        return view('admin.dashboard');
    });
});

Penyebab: Middleware role belum didaftarkan di Kernel.php.

Cara Memperbaiki:

Buka file app/Http/Kernel.php dan tambahkan middleware Spatie:

protected $routeMiddleware = [
    // Middleware lainnya
    'role' => \\Spatie\\Permission\\Middlewares\\RoleMiddleware::class,
    'permission' => \\Spatie\\Permission\\Middlewares\\PermissionMiddleware::class,
];

Setelah didaftarkan, middleware dapat digunakan tanpa error.

3. Salah Menentukan Role atau Permission yang Tidak Ada

Kesalahan ini terjadi ketika role atau permission yang digunakan pada middleware belum dibuat atau salah penulisan:

Route::middleware(['role:superadmin'])->group(function () {
    Route::get('/superadmin/dashboard', function () {
        return view('superadmin.dashboard');
    });
});

Penyebab: Role superadmin belum dibuat di database atau salah nama. Akibatnya, middleware tidak akan memberikan akses meskipun user memiliki role lain.

Cara Memperbaiki:

Pastikan role superadmin dibuat terlebih dahulu, misalnya melalui seeder:

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

Role::create(['name' => 'superadmin']);

Atau periksa role yang ada sebelum menggunakannya di route:

Route::middleware(['role:admin'])->group(function () { // Gunakan role yang sudah ada
    Route::get('/admin/dashboard', function () {
        return view('admin.dashboard');
    });
});

Dengan memastikan role atau permission sudah tersedia, middleware akan bekerja sebagaimana mestinya.

Ketiga kesalahan ini sering ditemui oleh pengembang pemula, terutama saat menggunakan Spatie Role Permission. Memastikan middleware, role, dan permission sudah benar akan mencegah error dan memastikan pengelolaan akses berjalan lancar.

Penutup dan Saran dari mentor

Sebagai kesimpulan, pengelolaan routing dan middleware di Laravel 11, terutama dengan integrasi package Spatie Role Permission, memberikan fleksibilitas yang luar biasa dalam mengatur otorisasi akses di aplikasi web. Kesalahan-kesalahan kecil seperti salah menentukan middleware atau role yang tidak sesuai dapat dengan mudah dihindari dengan pemahaman yang mendalam dan praktik yang konsisten.

Bagi programmer pemula, belajar Laravel adalah langkah strategis untuk mempersiapkan diri menghadapi kebutuhan pasar yang terus berkembang. Laravel tidak hanya menawarkan kemudahan penggunaan, tetapi juga didukung oleh komunitas besar dan dokumentasi lengkap, menjadikannya salah satu framework PHP yang paling banyak diminati.

Untuk memulai atau memperdalam pembelajaran, Anda dapat memanfaatkan platform seperti BuildWithAngga yang menyediakan kursus dengan akses seumur hidup. Selain itu, Anda mendapatkan manfaat tambahan seperti kesempatan membangun portofolio berkualitas yang dapat meningkatkan daya saing Anda di pasar kerja, serta konsultasi langsung dengan mentor yang berpengalaman.

Dengan konsistensi belajar dan dukungan dari platform yang tepat, Anda dapat menguasai Laravel dan memanfaatkannya untuk membangun karier yang sukses di industri teknologi.