Pendahuluan — siapa boleh ubah catatan pinjam?
Artikel ini adalah #66 (ini) di Seri 5: Laravel Lanjutan. Setelah daftar pinjam panjang dirapikan di Pagination, Filter & Pencarian (#65), pertanyaan berikutnya muncul: siapa boleh mengubah slip pinjam orang lain?
Tanpa aturan izin, siapa saja bisa mengubah catatan pinjam milik anggota lain — berbahaya. Hari ini kita belajar policy (aturan izin): cek pemilik dulu, tolak dengan 403 kalau bukan pemilik, dan izinkan petugas (staf) lewat aturan sederhana.
Awam: bayangkan kartu anggota perpustakaan. Hanya pemilik kartu (atau petugas resmi di loket) yang boleh mengubah catatan pinjam miliknya. Itu inti aturan izin (policy). Pemanggil API — aplikasi atau alat yang memanggil API — harus dikenali dulu sebelum server mengizinkan ubah data.
Prasyarat: sudah selesai Pagination, Filter & Pencarian (#65), paham fondasi Instal PHP, Composer & Proyek Laravel (#56) / Struktur Folder,
.env& Artisan Laravel (#57). Pakai Laravel 13+ — butuh PHP 8.3+.
Spesifikasi fitur — apa yang selesai hari ini?
Tiga hal ini yang kita kejar:
- Cek pemilik — sebelum ubah, pastikan
callerIdsama dengananggota_iddi catatan pinjam (atau pemanggil adalah staf). - Jawaban jelas saat ditolak — status
403dengan pesan awam “Tidak punya izin”. - Aturan terpusat — logika “boleh/tidak” tidak tersebar di banyak tempat; di Laravel dipindah ke kelas Policy.
Awam: selesai artikel ini, kamu belum merapikan bentuk JSON jawaban. Kamu sedang mengunci siapa boleh ubah slip pinjam di proyek perpustakaan mini — pemilik atau staf saja. Format JSON yang cantik datang di artikel berikutnya tentang API Resource.
Istilah — ringkas untuk aturan izin
| Istilah | Arti awam | Catatan |
|---|---|---|
| Aturan izin / policy | Daftar “siapa boleh apa” | Bukan kata sandi login |
anggota_id |
ID anggota pemilik catatan pinjam | Dari relasi di artikel relasi Eloquent sebelumnya |
403 vs 401 / login |
403 = sudah dikenali tapi tidak punya izin · 401 = belum login |
Pesan awam: “Tidak punya izin” untuk 403 |
authorize |
Perintah “cek aturan izin dulu” | Di Laravel, sebelum aksi sensitif di pengatur kode |
| Kelas Policy | File tempat aturan ditulis rapi | Contoh: PeminjamanPolicy |
| Staf | Petugas perpustakaan yang boleh mengubah catatan anggota | Override sederhana: $isStaf === true |
Urutan belajar kita: array PHP dulu -> cek pemilik dengan if -> baru bungkus Laravel Policy. Kalau loncat langsung ke Policy tanpa memahami anggota_id, pesan 403 sering terasa misterius.
Persiapan — alat yang kamu buka
Alat yang dipakai di artikel ini (fondasi dari Instal PHP, Composer & Proyek Laravel (#56) dan Struktur Folder, .env & Artisan Laravel (#57) — tidak ada unduhan Composer baru hari ini):
- Explorer — cek folder proyek
perpustakaan-api, lalu lihatapp\Http\Controllersdanapp\Policiesuntuk pengatur kode dan aturan izin. - Terminal — Laragon: menu Terminal · XAMPP: tombol Shell. Hindari CMD/PowerShell dari Start Menu kalau PATH PHP-mu belum rapi.
- Editor teks — Notepad / VS Code — untuk membuka pengatur kode. Contoh:
notepad app\Http\Controllers\PeminjamanController.phpdannotepad app\Policies\PeminjamanPolicy.php. - Browser — opsional. Inti uji hari ini ada di terminal; browser berguna kalau kamu sudah menjalankan
php artisan servedan ingin uji lewat alamat URL.
Awam: untuk artikel ini satu terminal sebenarnya cukup — jalankan php laravel_policy_otorisasi_api_demo.php di folder proyek. Kalau php artisan serve dari artikel sebelumnya masih hidup, pakai terminal kedua untuk demo PHP dan perintah curl.exe saat menguji rute Laravel. Kalau butuh jendela kedua: Laragon — klik menu Terminal lagi · XAMPP — klik tombol Shell lagi, lalu cd ke folder proyek yang sama.
Buka terminal Laragon/Shell XAMPP, masuk ke folder proyek:
cd C:\laragon\www\perpustakaan-api
Di XAMPP biasanya: cd C:\xampp\htdocs\perpustakaan-api. Sesuaikan kalau foldermu beda.
Install-dari-nol: kalau php atau composer belum dikenali terminal, kembali dulu ke Instal PHP, Composer & Proyek Laravel (#56). Kalau struktur folder proyek masih membingungkan, ulangi Struktur Folder, .env & Artisan Laravel (#57).
Kenapa PHP biasa dulu?
Kalau langsung loncat ke kelas Policy di Laravel, pemula sering bingung: kenapa ditolak? Maka kita mulai dari array PHP biasa supaya cek anggota_id terlihat jelas sebelum dibungkus authorize.
<?php
// Mini: cek pemilik sebelum ubah status pinjam.
$pinjam = ["id" => 10, "anggota_id" => 1, "judul" => "Dasar PHP", "status" => "aktif"];
$callerId = 2; // bukan pemilik
if ($callerId !== $pinjam["anggota_id"]) {
http_response_code(403);
echo json_encode(["pesan" => "Tidak punya izin"], JSON_UNESCAPED_UNICODE), PHP_EOL;
exit;
}
$pinjam["status"] = "kembali";
echo json_encode(["ok" => true, "data" => $pinjam], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), PHP_EOL;
Awam: anggota_id di catatan harus sama dengan siapa yang memanggil (callerId). Beda? Tolak dengan 403 — artinya “Tidak punya izin”, bukan “data hilang” (404). Login menjawab “siapa kamu”; aturan izin menjawab “apakah kamu boleh ubah baris ini”.
Alur izin — cek pemilik dulu
Gerakan yang benar selalu sama:
- Kenali pemanggil — siapa yang login / kartu anggota mana.
- Temukan catatan — pinjam ada? Kalau tidak, jawab
404. - Bandingkan pemilik —
anggota_idcatatan vscallerId, atau cek apakah pemanggil staf. - Izinkan atau tolak — pemilik/staf boleh ubah (
200), lainnya403“Tidak punya izin”.
<?php
// Salin ke file misalnya izin-cek.php lalu jalankan: php izin-cek.php
$pinjam = [
["id" => 10, "anggota_id" => 1, "judul" => "Dasar PHP", "status" => "aktif"],
["id" => 11, "anggota_id" => 2, "judul" => "Belajar Laravel", "status" => "aktif"],
];
function ubahStatusPinjam(array $pinjam, int $pinjamId, int $callerId, string $statusBaru, bool $isStaf = false): array
{
$row = null;
foreach ($pinjam as $p) {
if ($p["id"] === $pinjamId) {
$row = $p;
break;
}
}
if ($row === null) {
return ["status" => 404, "body" => ["pesan" => "Catatan pinjam tidak ketemu"]];
}
if (! $isStaf && $row["anggota_id"] !== $callerId) {
return ["status" => 403, "body" => ["pesan" => "Tidak punya izin"]];
}
return [
"status" => 200,
"body" => ["ok" => true, "id" => $pinjamId, "status" => $statusBaru],
];
}
$r = ubahStatusPinjam($pinjam, 10, 2, "kembali");
http_response_code($r["status"]);
echo json_encode($r["body"], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), PHP_EOL;
Awam — cara menguji bagian ini: salin potongan di atas ke izin-cek.php, lalu di terminal jalankan php izin-cek.php. Kalau muncul JSON dengan "pesan": "Tidak punya izin" dan status 403, cek pemilik sudah sehat. Ubah $callerId ke 1 (pemilik) dan jalankan lagi — harus dapat 200 dengan ok: true.
Laravel — cuplikan Policy & authorize (bukan file mandiri)
Di proyek Laravel, aturan izin ditulis di kelas Policy, lalu dipanggil lewat authorize di pengatur kode sebelum aksi sensitif.
<?php
// Cuplikan Laravel (bukan file mandiri)
// app/Policies/PeminjamanPolicy.php
namespace App\Policies;
use App\Models\Peminjaman;
use App\Models\User;
class PeminjamanPolicy
{
public function update(User $user, Peminjaman $peminjaman): bool
{
return $user->id === $peminjaman->anggota_id || $user->is_staf;
}
}
<?php
// Cuplikan Laravel (bukan file mandiri)
// app/Http/Controllers/PeminjamanController.php
public function update(Request $request, Peminjaman $peminjaman)
{
$this->authorize('update', $peminjaman);
$peminjaman->update($request->only('status'));
return response()->json(['ok' => true, 'data' => $peminjaman]);
}
Awam: PeminjamanPolicy::update = aturan “boleh ubah kalau pemilik sama atau staf”. authorize('update', $peminjaman) = jalankan aturan itu dulu; gagal -> Laravel otomatis jawab 403. Aturan di satu file Policy lebih mudah dirawat daripada if berulang di banyak tempat. Cuplikan ini bukan file mandiri — tempel ke proyek kalau rute ubah pinjam sudah ada.
Kalau php artisan serve sudah jalan di terminal pertama, uji di terminal kedua. Di Windows ketik curl.exe (bukan alias curl saja) supaya PowerShell tidak bingung:
curl.exe -X PUT "http://127.0.0.1:8000/api/peminjaman/10" -H "Content-Type: application/json" -d "{\"status\":\"kembali\"}"
Awam: respons JSON dari curl.exe adalah cara cepat melihat apakah aturan izin bekerja sebelum membuka browser. Kalau muncul 403 dengan pesan jelas, policy menolak dengan benar. Kalau 404, catatan pinjam mungkin tidak ada — beda masalah dari izin.
Pola Dasar — aturan izin yang rapi
-
1
Kenali pemanggil
Siapa yang login / kartu anggota mana — fondasi dari langkah sebelumnya. -
2
Temukan catatan
Pinjam ada? Kalau tidak, jawab404jelas. -
3
Bandingkan pemilik
anggota_idcatatan vscallerId— PHPifdulu, termasuk cek staf. -
4
Tolak dengan 403
Pesan awam “Tidak punya izin” — jangan biarkan orang lain ubah. -
5
Pindah ke Policy
Tulis aturan di kelasPeminjamanPolicy; panggilauthorizesebelum ubah. -
6
Uji tiga jalur
Pemilik benar · bukan pemilik · catatan tidak ada · staf override.
Kode lengkap — demo mandiri
Simpan sebagai laravel_policy_otorisasi_api_demo.php, lalu jalankan php laravel_policy_otorisasi_api_demo.php:
<?php
declare(strict_types=1);
$pinjam = [
["id" => 10, "anggota_id" => 1, "judul" => "Dasar PHP", "status" => "aktif"],
["id" => 11, "anggota_id" => 2, "judul" => "Belajar Laravel", "status" => "aktif"],
];
function ubahStatusPinjam(array $pinjam, int $pinjamId, int $callerId, string $statusBaru, bool $isStaf = false): array
{
$row = null;
foreach ($pinjam as $p) {
if ($p["id"] === $pinjamId) {
$row = $p;
break;
}
}
if ($row === null) {
return ["status" => 404, "body" => ["pesan" => "Catatan pinjam tidak ketemu"]];
}
if (! $isStaf && $row["anggota_id"] !== $callerId) {
return ["status" => 403, "body" => ["pesan" => "Tidak punya izin"]];
}
return [
"status" => 200,
"body" => ["ok" => true, "id" => $pinjamId, "status" => $statusBaru],
];
}
function demo(string $judul, callable $aksi): void
{
echo "=== {$judul} ===", PHP_EOL;
$hasil = $aksi();
echo "status: ", $hasil["status"], PHP_EOL;
echo json_encode($hasil["body"], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), PHP_EOL, PHP_EOL;
}
demo("Bukan pemilik -> 403", function () use ($pinjam) {
return ubahStatusPinjam($pinjam, 10, 2, "kembali");
});
demo("Pemilik benar -> 200", function () use ($pinjam) {
return ubahStatusPinjam($pinjam, 10, 1, "kembali");
});
demo("Catatan tidak ada -> 404", function () use ($pinjam) {
return ubahStatusPinjam($pinjam, 99, 1, "kembali");
});
demo("Staf override -> 200", function () use ($pinjam) {
return ubahStatusPinjam($pinjam, 10, 2, "kembali", true);
});
Awam: empat skenario di atas menunjukkan pola respons yang wajar: bukan pemilik ditolak, pemilik boleh, catatan hilang dapat 404, staf boleh ubah meski bukan pemilik. Fungsi ubahStatusPinjam adalah inti logika; demo(...) hanya membungkus output agar mudah dibaca di terminal.
Kesalahan umum
| Gejala | Penyebab tipikal | Perbaikan awam |
|---|---|---|
| Siapa saja bisa ubah pinjam orang lain | Lupa cek anggota_id vs callerId |
Cek pemilik sebelum ubah — salin pola dari izin-cek.php |
403 tanpa pesan yang jelas |
Respons kosong atau teknis | Tulis “Tidak punya izin” yang awam pahami |
Bingung 403 vs 404 |
Keduanya dianggap “gagal” | 404 = tidak ketemu · 403 = ada tapi tidak punya izin |
403 padahal yakin pemilik |
callerId salah atau belum login |
Pastikan identitas pemanggil benar sebelum cek policy |
| Aturan tersebar di banyak file | Copy-paste if berulang |
Kumpulkan di kelas PeminjamanPolicy |
curl aneh atau error di PowerShell |
Alias curl di PowerShell bukan curl.exe |
Ketik curl.exe persis seperti contoh, atau uji lewat browser |
Latihan singkat
- Ubah demo: tambah kasus “pemilik benar ubah pinjam id 11” dan bandingkan dengan kasus bukan pemilik.
- Jelaskan ke teman: beda
403(Tidak punya izin) dengan404(tidak ketemu). - Tulis satu kalimat: kenapa aturan izin lebih rapi di kelas Policy daripada
ifdi banyak tempat.
FAQ singkat
Apakah Policy menggantikan login?
Tidak. Login menjawab “siapa kamu” (401 kalau belum). Policy menjawab “apakah kamu boleh melakukan ini pada baris ini” (403 kalau tidak).
Haruskah selalu pakai kelas Policy?
Untuk belajar, if PHP di izin-cek.php sudah cukup memahami ide. Di proyek Laravel nyata, Policy membantu merapikan aturan saat bertambah.
Tool apa yang dibuka dulu?
Explorer untuk memastikan folder proyek benar (Controllers + Policies), satu terminal untuk demo PHP, editor untuk pengatur kode. Kalau serve hidup, terminal kedua untuk curl.exe.
Potongan sintaks diuji di mana?
Langkah tengah (cek pemilik) salin ke izin-cek.php, lalu jalankan php izin-cek.php. Demo lengkap diuji dengan php laravel_policy_otorisasi_api_demo.php. Cuplikan Laravel ditempel ke app\Http\Controllers\PeminjamanController.php dan app\Policies\PeminjamanPolicy.php; kalau rute sudah ada, uji dengan curl.exe di terminal kedua.
Ke mana setelah ini?
Berikutnya alami: API Resource: Rapikan Bentuk JSON (#67) — rapikan bentuk JSON jawaban.
Kesimpulan
Kamu sudah mengunci siapa boleh ubah catatan pinjam: cek pemilik dengan if PHP dulu, lalu pindahkan ke aturan izin (Policy) dan authorize di Laravel. Status 403 = “Tidak punya izin” — jelas untuk pemanggil API. Staf boleh lewat override sederhana sebelum aturan makin rumit.
Seri 5 progress: langkah #66 (ini) · 3/7 Laravel Lanjutan · prasyarat: Pagination, Filter & Pencarian (#65) LIVE. Berikutnya: API Resource: Rapikan Bentuk JSON (#67).