[Praktikum - 2403015047 - Risma Pratiwi]
Topik: Manipulasi Data & Keamanan Framework PHP
Artikel ini membahas beberapa masalah penting dalam pengembangan aplikasi Laravel, mulai dari efisiensi query, keamanan input, validasi backend, transaksi database, sampai pengelolaan data terhapus. Setiap bagian disusun berdasarkan hasil praktikum, contoh kode, analisis singkat, dan tempat untuk menaruh screenshot bukti percobaan.
Analisis N+1 Query Problem & Solusinya (Eager Loading)
N+1 Query Problem terjadi saat aplikasi mengambil data utama satu kali, lalu untuk setiap data relasi yang dibutuhkan Laravel menjalankan query tambahan berulang-ulang. Akibatnya jumlah query menjadi banyak dan performa aplikasi menurun. Pada kasus produk dan kategori, masalah ini biasanya muncul ketika kategori dipanggil di dalam loop Blade tanpa eager loading.
Contoh Program yang Memicu N+1
Controller sebelum diperbaiki:
public function index()
{
$products = Product::all();
return view('products.index', compact('products'));
}
Blade View yang memicu N+1:
@foreach ($products as $product)
<tr>
<td>{{ $product->name }}</td>
<td>{{ $product->category->name }}</td>
</tr>
@endforeach
Analisis: kode di atas terlihat sederhana, tetapi relasi kategori dipanggil satu per satu di dalam loop. Jika ada 10 produk, Laravel bisa saja menjalankan 1 query untuk produk dan 10 query lagi untuk kategori. Kondisi seperti ini disebut N+1 Query dan harus dihindari karena tidak efisien.
Perbaikan dengan eager loading:
public function index()
{
$products = Product::with('category')->get();
return view('products.index', compact('products'));
}
Analisis perbaikan: dengan with('category'), Laravel mengambil data produk dan kategori secara lebih efisien.
Query yang tadinya membengkak akan jauh berkurang karena relasi sudah dimuat sejak awal.
[Screenshot 1: Controller sebelum diperbaiki]
[Screenshot 2: Blade View yang memicu N+1]
[Screenshot 3: Debugbar/Telescope yang menunjukkan query membengkak]
[Screenshot 4: Controller setelah memakai with()]
[Screenshot 5: Debugbar/Telescope setelah query berkurang]
Eksperimen Keamanan Mass Assignment & White-listing
Mass Assignment Vulnerability adalah celah yang muncul ketika attacker mengirim field tambahan yang sebenarnya tidak boleh diisi, seperti is_admin atau role.
Jika model tidak dibatasi dengan baik, field sensitif bisa ikut tersimpan ke database.
Simulasi Serangan
{
"name": "attacker",
"email": "attacker@mail.com",
"password": "password123",
"is_admin": 1
}
Analisis: jika data seperti ini diproses langsung dengan User::create($request->all()), maka semua field dari request bisa ikut masuk.
Karena itu perlu whitelist agar hanya atribut tertentu saja yang boleh disimpan.
Model Setelah Diamankan
protected $fillable = [
'name',
'email',
'password'
];
Atau bisa juga memakai blacklist:
protected $guarded = [
'is_admin',
'role'
];
Analisis perbaikan: dengan $fillable, Laravel hanya mengizinkan field yang ada di daftar putih untuk diisi otomatis.
Field ilegal seperti is_admin akan diabaikan oleh framework.
[Screenshot 1: Request Postman/Bruno dengan parameter ilegal]
[Screenshot 2: Database sebelum diamankan]
[Screenshot 3: Kode model setelah ditambah $fillable atau $guarded]
[Screenshot 4: Hasil uji ulang setelah diamankan]
Validasi Form Request & Parameter Binding Tangguh
Validasi frontend memang membantu, tetapi tidak boleh dijadikan benteng utama karena input browser mudah dimanipulasi. Karena itu validasi backend lebih penting. Laravel menyediakan Form Request agar aturan validasi lebih rapi dan tidak bercampur dengan logic controller.
Contoh Form Request
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class StoreArticleRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'title' => [
'required',
'string',
'max:255',
Rule::unique('articles', 'title')
],
'content' => [
'required',
'string',
'min:20'
],
];
}
public function messages(): array
{
return [
'title.required' => 'Judul wajib diisi.',
'title.unique' => 'Judul artikel sudah digunakan.',
'content.required' => 'Isi artikel wajib diisi.',
'content.min' => 'Isi artikel minimal 20 karakter.',
];
}
}
Analisis: Form Request membuat validasi lebih terpusat, rapi, dan mudah dipelihara. Jika input tidak sesuai aturan, Laravel otomatis menampilkan error tanpa perlu pengecekan manual yang panjang di controller.
Laravel juga menggunakan parameter binding pada Query Builder dan Eloquent. Artinya nilai input user tidak digabung langsung ke SQL mentah, tetapi dikirim sebagai parameter terpisah sehingga lebih aman dari SQL Injection.
[Screenshot 1: File Form Request]
[Screenshot 2: Input yang gagal validasi]
[Screenshot 3: Pesan error otomatis dari framework]
Simulasi Kegagalan Sistem Menggunakan Database Transactions
Transaksi database dipakai saat satu proses melibatkan beberapa query yang saling berhubungan. Prinsip dasarnya adalah atomisitas, yaitu semua langkah harus berhasil bersama atau gagal bersama. Jika satu langkah gagal, maka seluruh perubahan harus dibatalkan agar data tetap konsisten.
Contoh Controller Transaksi
use Illuminate\Support\Facades\DB;
public function checkout(Request $request)
{
DB::beginTransaction();
try {
$order = Order::create([
'user_id' => auth()->id(),
'total' => $request->total
]);
throw new \Exception('Koneksi internet terputus!');
OrderItem::create([
'order_id' => $order->id,
'product_id' => $request->product_id,
'qty' => $request->qty
]);
DB::commit();
return response()->json(['message' => 'Checkout berhasil']);
} catch (\Exception $e) {
DB::rollBack();
return response()->json(['message' => $e->getMessage()], 500);
}
}
Analisis: saat exception sengaja dilempar di tengah proses, Laravel akan menjalankan rollback. Akibatnya data yang sempat masuk sebelum error ikut dibatalkan, sehingga database tetap bersih dan tidak menyisakan data sampah.
[Screenshot 1: Kode controller transaksi]
[Screenshot 2: Baris throw new Exception di tengah proses]
[Screenshot 3: Database setelah error dijalankan]
[Screenshot 4: Bukti rollback berhasil]
Implementasi Fitur Trash & Restore dengan Soft Deletes
Soft Delete dipakai ketika data tidak ingin dihapus permanen, tetapi hanya disembunyikan dulu. Ini cocok untuk data yang masih mungkin dipulihkan. Sementara itu, Hard Delete dipakai jika data memang harus dihapus permanen.
Migration Soft Delete
Schema::table('articles', function (Blueprint $table) {
$table->softDeletes();
});
Model
use Illuminate\Database\Eloquent\SoftDeletes;
class Article extends Model
{
use SoftDeletes;
}
Contoh Kueri
Hapus data sementara:
Article::find($id)->delete();
Tampilkan data di kotak sampah:
Article::onlyTrashed()->get();
Kembalikan data:
Article::onlyTrashed()->where('id', $id)->restore();
Analisis: dengan soft delete, data tidak benar-benar hilang dari database karena Laravel hanya mengisi kolom deleted_at.
Cara ini memudahkan fitur kotak sampah dan restore jika data dibutuhkan lagi.
[Screenshot 1: Struktur tabel dengan kolom deleted_at]
[Screenshot 2: Kode migration]
[Screenshot 3: Kode delete(), onlyTrashed(), dan restore()]
[Screenshot 4: Halaman “Kotak Sampah”]
Penutup
Dari praktikum ini dapat disimpulkan bahwa keamanan dan efisiensi query sangat penting dalam pengembangan aplikasi Laravel. Eager loading membantu mengurangi query berlebih, mass assignment bisa diamankan dengan whitelist, validasi backend menjaga integritas input, transaksi database melindungi konsistensi data, dan soft delete memberi fleksibilitas dalam pengelolaan data yang dihapus.
Komentar
Posting Komentar