~ We are changing the world with technology. ~

Matt Mullenweg

Membuat Access Control Laravel – Chapter 1

Membuat Access Control Laravel – Chapter 1

2117 Dilihat

Memulai kisah baru dalam seri belajar laravel bareng Daengweb.id. Kali ini kita akan belajar tentang access control yang akan kita rangkai menjadi beberapa chapter. Tapi cerita kita merupakan lanjutan dari cerita-cerita sebelumnya. Maka apa yang telah dibuat sebelumnya akan kita manfaatkan pada tutorial kali ini.

Secara default user dapat melakukan registrasi dan login, akan tetapi tidak memiliki batasan untuk mengontrol user tersebut. Sebagai contoh, seharusnya terdapat user yang dapat mengedit sebuah post ? Ataukah hanya dibatasi pada user yang membuat post tersebut ? Dan tentu saja untuk mewujudkan hal tersebut, alangkah lebih baik jika kita membuat admin area untuk membuat access control tersebut.

Menggunakan Trait

Kita bisa menambahkan sebuah method ke user model yang akan mengecek apakah terdapat records yang dimiliki oleh user tersebut, namun pada tutorial ini saya lebih prefer menggunakan sebuah trait. Alasannya sederhana, agar lebih rapi dan maintenable.

Langsung saja kita buat sebuah folder dengan nama AuthTraits pada folder App/Http. Kemudian kita buat sebuah file dengan nama OwnsRecord.php, yang terlihat seperti ini :

Kita telah memiliki sebuah file dengan nama OwnsRecord.php yang terdapat didalam folder AuthTraits. Tambahkan syntax berikut :

<?php
namespace App\Http\AuthTraits;
use Illuminate\Support\Facades\Auth;

trait OwnsRecord
{
	public function userNotOwnerOf($modelRecord)
	{
		return $modelRecord->user_id != Auth::id();
	}

	public function currentUserOwns($modelRecord)
	{
		return $modelRecord->user_id === Auth::id();
	}

	public function adminOrCurrentUserOwns($modelRecord)
	{
		if (Auth::user()->is_admin == 1) {
			return true;
		}
		return $modelRecord->user_id === Auth::id();
	}
}

Seperti yang terlihat, terdapat namespace sesuai directory trait dan juga menggunakan Auth Facade:

namespace App\Http\AuthTraits;
use Illuminate\Support\Facades\Auth;

Kita akan menggunakan Auth::id(), yang akan me-return id user yang sedang login untuk kemudian mencek atribut user_id pada model yang sedang menanganinya. Sebagai contoh, pada Post mode, kita memiliki user_id, yang menyimpan sekaligus menjadi pengenal user yang mana yang membuat record tersebut. Dan tugas kita selanjutnya adalah memastikan kecocokan id, jadi anda dapat melihatnya pada method currentUserOwns:

public function currentUserOwns($modelRecord)
{
    return $modelRecord->user_id === Auth::id();
}

fungsi method diatas adalah mengecek atribut user_id dan Auth::id() apakah terdapat kecocokan. Pada method yang berbeda kita juga memiliki sebuah method yang berfungsi untuk mengecek jika terdapat ketidakcocokkan user_id dan Auth::id(), yakni pada method userNotOwnerOf:

public function userNotOwnerOf($modelRecord)
{
    return $modelRecord->user_id != Auth::id();
}

Dengan memanfaatkan trait yang telah kita buat, maka kita dapat melakukan hal seperti berikut :

if ($this->userNotOwnerOf($post)) {
    //throw new someException;
}

atau hal yang serupa dengan memanfaatkan method lainnya :

if (!this->currentUserOwns($post)) {
    //throw new SomeException
}

Tampaknya method userNotOwnerOf dan currentUserOwns serupa tapi tak sama, dan mungkin saja salah satunya saja sudah cukup untuk digunakan. Tapi dengan maksud pembelajaran saya membuatnya kedalam dua method. Kedepannya silahkan berkreasi dalam membuat dan memanfaatkan sebuah method.

Terakhir, kita memiliki sebuah method yang akan mengecek apa user yang login adalah pemilik record atau admin:

public function adminOrCurrentUserOwns($modelRecord)
{
	if (Auth::user()->is_admin == 1) {
		return true;
	}
	return $modelRecord->user_id === Auth::id();
}

Ini akan sangat berguna jika anda ingin mengizinkan admin dan juga pemilik record untuk mengedit sebuah record.

Agar kita bisa melihat apakah is_admin sama dengan satu, dalam artian adalah benar maka kita harus memiliki field tersebut pada users table. Kita akan menambahkan beberapa field pada user table, tapi sebelum melakukannya. Kita akan melakukan testing pada trait yang telah dibuat. Silahkan tambahkan trait pada PostContorller:

class PostController extends Controller
{
    use OwnsRecord;

Dan juga tambahkan use statement pada use statements section :

use App\Http\AuthTraits\OwnsRecord;

Kemudian mari kita tambahkan salah satu trait method kedalam update method seperti berikut :

public function update(Request $request)
{
    $this->validate($request, [
       'title' => 'required|max:255|unique:posts,title'
    ]);

    $post = Post::find($id);
    if ($this->userNotOwnerOf($post)){
       dd('kamu bukan pemilik post ini');
    }

    $post->update([
        'user_id' => Auth::id(), 
        'title' => $request->title
    ]);
    return redirect(route('post'))
}

Seperti yang anda lihat, kita hanya menambahkan potongan code ini :

if ($this->userNotOwnerOf($post)){
  dd('kamu bukan pemilik post ini');
}

Untuk melakukan uji coba, pada record post yang telah ada, silahkan edit user_id dengan menggunakan id user yang sedang tidak login pada proses uji coba kali ini. Pada kasus kali ini, saya menggunakan user_id = 2, dimana id tersebut tidak terdapat pada users table.

Jadi ketika anda mencoba melakukan update data post, anda akan mendapatkan pesan berikut :

"kamu bukan pemilik post ini"

Dengan demonstrasi ini sekaligus kita belajar bagaimana menggunakan method dd() untuk memvalidasi dan mengetahui apakah anda mendapatkan hasil yang diharapkan atau tidak.

Tentunya, dalam real application, kita tidak bisa menggunakan die dan dump (dd), jadi yang akan kita lakukan selanjutnya adalah membuat pesan custom error menggunakan exception.  Opps, exception sudah disinggung tapi akan dilanjutkan pada artikel selanjutnya agar tidak jenuh. Jadi sampai jumpa di artikel selanjutnya. Semoga bermanfaat.

Backend Developer iTechShark, salah satu perusahaan asal Amerika. Senang dengan teknologi baru. Laravel addict yang tidak fanatik. Merekam jejak dengan menulis

Aplikasi Laundry (Laravel 5.8 - Vue.js - SPA) #8: Manage Customers Laravel VueJS

Aplikasi Laundry (Laravel 5.8 - Vue.js -...

Pelanggan menjadi bagian yang penting dari sebuah perusahaan laundry, maka fitur yang akan dikerjakan pada serial ini adalah sebuah fitur untuk mengelola pelanggan. Adapun schema yang dirancang dimana...

Aplikasi Laundry (Laravel 5.8 - Vue.js - SPA) #7: Push Notification Expenses Laravel VueJS

Aplikasi Laundry (Laravel 5.8 - Vue.js -...

Dalam setiap kegiatan berwirausaha pasti terdapat biaya biaya yang harus dikeluarkan untuk menjalankan operasional dari usaha tersebut, maka dalam aplikasi ini, kita tidak hanya akan mencatat transaks...

Aplikasi Laundry (Laravel 5.8 - Vue.js - SPA) #6: Role & User Permissions Laravel VueJS

Aplikasi Laundry (Laravel 5.8 - Vue.js -...

Sambil menikmati secangkir kopi ini, kutuliskan serial lanjutan membuat Aplikasi Laundry menggunakan Laravel 5.8 & Vue.js dengan metode SPA (Single Page Application) yang telah memasuki serial ke-6 ny...

Komentar