Laravel Middleware Route as Model


Laravel Middleware Route as Model

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

Image DB

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 Image

Kita mempunya 2 data user, yaitu user Fika & User Sanjaya. Lalu kita punya data order seperti dibawah ini

Image

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 Image

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 Image

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

Image

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!


Mohammad Ricky Sanjaya
Hi! I'm Sanjaya Back End Developer. You can discuss with me about web technology and more!

Suka dengan tulisan di SantriKoding? Kamu bisa memberikan dukungan dengan berdonasi atau bagikan konten ini di sosial media. Terima kasih atas dukungan Anda!

KEBIJAKAN KOMENTAR

Saat memberikan komenatar silahkan memberikan informasi lengkap tentang error, seperti: screenshot, link kode, dll. Baca aturan komentar kami