Halo teman-teman, kembali lagi kita di website Santrikoding.com. Kali ini kita akan membahas lagi tentang Laravel Tips yaitu laravel middleware route request sebagai model. Apa sih maksudnya? Yuk kita bahas
Latar Belakang
Pernahkah kamu membuat dimana suatu data tidak semua orang bisa mengakses nya? Hanya user tertentu saja / hanya user yang memiliki data tersebut yang hanya boleh mengakses data tersebut. Nah kali ini kita akan membahas bagaimana cara melindungi data tersebut dengan cara route request sebagai model.
Definisi
Melanjutkan pembahasan kita kemarin tentang laravel route model binding yang bisa teman-teman baca disini. Jadi laravel middleware route request sebagai model adalah kita membawa model / membinding para route kita lalu membuat nya sekaligus untuk middleware melindungi data kita untuk orang tertentu saja. Mungkin masih bingung yah? Yuk kita langsung studi kasus saja.
Contoh Kasus
Kita akan mengambil kasus order, dimana data order pasti memiliki field / kolom customer_id yang artinya adalah kolom pembeli. Nah dalam kasus ini, customer_id berelasi dengan table users, Bisa dilihat relasi diagram dibawah ini
Dari gambar diatas, kita artikan bahwa user dapat membuat order untuk dirinya sendiri. Maka seharusnya setiap user hanya boleh melihat order nya sendiri dan tidak boleh melihat order orang lain.
Let's Code!!
Sekarang buat asumsi kita mempunyai data user seperti dibawah ini
Kita mempunya 2 data user, yaitu user Fika & User Sanjaya. Lalu kita punya data order seperti dibawah ini
Data order diatas menunjukan
- Order nomor ORD-001 adalah order milik user Fika, dan
- Order nomor ORD-002 adalah order milik user sanjaya
Sekarang, kita akan membuat simulasi dengan menggunakan user Fika. Ingat ya kita login menggunakan user Fika. Kita coba buat untuk halaman list order nya dahulu.
Kode pada route
Route::get("/orders", [OrderController::class, "index"]);
Lalu pada controller, kita buat kode seperti ini
public function index()
{
$data = [
"orders" => Order::where("user_id", Auth::user()->id)->paginate(10)
];
return view("orders.index", $data);
}
Dan pada view kita tulis seperti ini
@extends('layouts.app')
@section('content')
<div class="container">
<div class="card">
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>Order Number</th>
<th>Order Date</th>
<th>Amount</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@forelse ($orders as $order)
<tr>`
<td>{{ $loop->iteration }}</td>
<td>{{ $order->order_number }}</td>
<td>{{ $order->order_date->format("d M Y") }}</td>
<td>{{ number_format($order->amount) }}</td>
<td>
<a href="/orders/{{ $order->id }}">Detail</a>
</td>
</tr>
@empty
<tr>
<td colspan="5" class="text-center">No data</td>
</tr>
@endforelse
</tbody>
</table>
{{ $orders->links() }}
</div>
</div>
</div>
@endsection
Maka hasilnya akan seperti ini
Oke sekarang kita akan membuat perlindungan untuk halaman detail order melalui middleware route request sebagai model agar hanya user tertentu yang dapat mengakses nya.
Kode untuk mengakses halaman detail sama seperti biasa, yaitu
<a href="/orders/{{ $order->id }}">Detail</a>
Dan pada route kita buat seperti ini
Route::get("/orders/{order}", [OrderController::class, "show"]);
Lalu pada controller kita buat seperti ini
public function show(Order $order)
{
return \view("orders.show", \compact("order"));
}
Kode diatas kita menggunakan route model binding dimana kita bisa langsung mengambil data tanpa harus membuat query builder. Lalu kode view kita seperti
@extends('layouts.app')
@section('content')
<div class="container mt-3">
<div class="card">
<div class="card-body">
<h5>Detail Order</h5>
<p>Order Number : {{ $order->order_number }}</p>
<p>Order Date : {{ $order->order_date->format("d M Y") }}</p>
<p>Amount : {{ number_format($order->amount) }}</p>
</div>
</div>
</div>
@endsection
Maka hasilnya akan seperti ini
Saat ini jika user fika mengakses langsung data order ORD-002 melalui url
http://127.0.0.1:8000/orders/2
maka masih bisa diakses. Bagaimana cara agar kita bisa melindungi data kita? Saat nya menggunakan middleware route model.
Pertama, kita membuat middleware nya dahulu dengan perintah
php artisan make:middleware AuthOrder
Maka akan otomatis dibuatkan middleware dengan nama AuthOrder.php. Daftarkan middleware baru kita didalam folder App\Http\Kernel.php dan tambahkan kode berikut didalam variable $routeMiddleware
"auth_order" => \App\Http\Middleware\AuthOrder::class,
Lalu pada file middleware AuthOrder.php kita isi seperti ini
public function handle(Request $request, Closure $next)
{
$order = $request->route("order");
if ($order->user_id == Auth::user()->id) {
return $next($request);
}
return \abort(403);
}
Dan terakhir, kita ubah route halaman detail kita menjadi seperti ini
Route::get("/orders/{order}", [OrderController::class, "show")->middleware("auth_order");
Oke sip sudah selesai kita melindungi halaman detail kita agar user tertentu yang bisa akses. Kenapa ? Kok bisa ya?
Pada kode middleware AuthOrder.php, kita membuat variable $order dengan di isi $request->route(“order”);, karena kita menerapkan kode route model binding maka secara magic laravel akan mengisi variable $order ini dengan model dari order sesuai yang diassign pada parameter controller kita.
Jadi, variable $order pada middleware kita sudah berisi model Order yang berisi data detailnya, sehingga kita tinggal membuat kondisi jika data order yang diakses user nya sama dengan user order, maka di izinkan, jika tidak maka akan diredirect ke halaman 403 forbidden. Kita coba test user Fika mengakses data order ORD-002 yang dimana data ini tidak boleh diakses karena bukan pemilik order tersebut. Jika kita akses maka hasilnya
Yak sesuai yang kita inginkan, hasilnya adalah 403 forbidden. Bagaimana? Sangat magic sekali kan:D
Kesimpulan
Metode ini adalah lanjutan seri sebelumnya tentang laravel route model binding yang dimana kita tinggal mengakses nya melalui middleware dengan menggunakan kode $request->route(“order”); maka secara otomatis laravel akan mengambil Model Order & data nya.
Cukup sekian tutorial seri Laravel Tips kali ini, terima kasih kepada para pembaca & nantikan tutorial menarik lain nya ya!