Membuat Access Control Laravel – Chapter 3

Membuat Access Control Laravel – Chapter 3

Access control sangat menarik untuk dibahas secara mendetail, maka melanjutkan seri sebelumnya yang telah membahas tentang exception, dan adapun poin yang akan kita capai dalam seri kali ini diantaranya :

  1. Menentukan hak akses untuk user yang terdaftar
  2. Menggunakan exception pada setiap tindakan user berdasarkan hak aksesnya
  3. Protect edit data berdasarkan kepemilikannya (hak akses)

Dan untuk melakukan hal diatas, kita akan menggunakan trait OwnsRecord pada model User. Dilain hal kita akan mengizinkan admin untuk dapat mengubah post yang tidak mereka miliki. Maka itu berarti perlu untuk memodifikasi model User.

Modifikasi Migration Table User

Ketikkan perintah berikut pada command line anda :

php artisan make:migration tambah_is_admin_dan_status_id_ke_users_table

Dapat kita temukan file tersebut pada folder database/migrations, dengan method up dan down yang masih kosong. Edit file tersebut sehingga menjadi seperti ini :

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class TambahIsAdminDanStatusIdKeUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function(Blueprint $table)
        {
            $table->boolean('is_admin')->default(false)->after('email');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function ($table) {
            $table->dropColumn('is_admin');
        });
    }
}

Seperti yang anda lihat, kita menambahkan 2 field. Pertama adalah field is_admin, dengan type boolean yang memiliki default value adalah false dan ditempatkn setelah field email.

$table->boolean('is_admin')->default(false)->after('email');

Tentunya pada method down, kita tambahkan drop column untuk menghapus field :

Schema::table('users', function ($table) {
     $table->dropColumn('is_admin');
});

jalankan command berikut pada command line :

php artisan migrate

maka anda akan mendapatkan table users menjadi seperti ini :

Setelah field baru ditambahkan, maka jangan lupa untuk mengubah $fillable property pada model User.

protected $fillable = [
   'name', 'email', 'is_admin', 'password',
];

sebelum kita mengeksplor perubahan yang lebih jauh lagi untuk admin, kita akan melakukan testing terlebih dahulu dengan menggunakan trait ownsRecord. Baiklah, silahkan ubah value dari is_admin menjadi 1 pada phpMyadmin :

Lakukan sedikit perubahan pada method update yang terdapat di PostController.php dan ubah bagian untuk mengecek kepemilikan dari sebuah record.

if ( ! $this->adminOrCurrentUserOwns($post)){
   throw new UnauthException;
}

Setelah melakukan perubahan tersebut, edit lalu update data pada post yang telah ada (jika bingung post yang mana, silahkan baca kembali artikel sebelumnya karena postingan ini saling terkait dan bersambung).

Jika sebelumnya yang dapat mengedit record adalah pemilik records tersebut atau dengan kata lain yang membuat post tersebut. Tapi kali ini karena anda bertindak sebagai Admin, maka anda bisa mengupdate records tersebut.

Perlu diperhatikan, pada method update, user_id akan berubah berdasarkan id yang didapatkan pada Auth::user() ketika anda melakukan update data. Jika anda tidak ingin hal tersebut terjadi, anda dapat mengubahnya dengan tidak mengeksekusi field tersebut pada method update.

Hak akses pada view

Jadi sekarang, kita menginginkan hal diatas juga berlaku pada view. Jika user tidak memiliki record atau juga bukan admin, mereka tidak akan mendapatkan link untuk mengedit data.

Langkah pertama yang harus kita lakukan adalah menempatkan trait OwnsRecord kedalam model User. Jadi, tambahkan use statement berikut pada tempatnya :

use App\Http\AuthTraits\OwnsRecord;

kemudian use OwnsRecord dalam class :

use Notifiable, OwnsRecord;

Maka model User akan menjadi seperti ini :

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Http\AuthTraits\OwnsRecord;

class User extends Authenticatable
{
    use Notifiable, OwnsRecord;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'is_admin', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function post()
    {
        return $this->hasMany(Post::class);
    }
}

Dan sekarang kita dapat memanggil methods yang dimilikinya dengan Auth::user(), seperti Auth::user()->adminOrCurrentUserOwns(). Maka penerapannya dalam view dengan case yang telah dijelaskan diatas akan menjadi seperti ini :

<table class="table table-hover">
	<thead>
		<tr>
		    <td>#</td>
			<th>Title</th>
			<th>Created at</th>
			<th></th>
		</tr>
	</thead>
	<tbody>
		@if ($post->count() > 0)
		@foreach ($post as $posts)
		<tr>
			<td></td>
			<td>{{ $posts->title }}</td>
			<td>{{ $posts->created_at }}</td>
			<td>
				@if(Auth::user()->adminOrCurrentUserOwns($posts))
				<a href="{{ url('post/' . $posts->id) }}" class="btn btn-warning btn-sm btn-flat">Edit</a>
				@endif
				<button class="btn btn-danger btn-sm btn-flat">Delete</button>
			</td>
		</tr>
		@endforeach
		@else
		<tr>
			<td colspan="3" class="text-center">Tidak ada data</td>
		</tr>
		@endif
	</tbody>
</table>

Jadi, selama kamu bukan admin dan post memiliki user_id yang berbeda dari user id yang sedang login, maka tombol edit tidak akan ditampilkan. Silahkan mengotak atik value is_admin dan juga user_id pada database anda untuk melihat bagaimana cara kerjanya.

Dan tentu saja sangat mudah untuk dipahami. Sekali lagi, sederhananya, jika admin atau owner maka tampilkan tombol edit, jika bukan maka tidak akan ditampilkan. Mudah bukan ?

Protect method edit

Tentu saja, kamu juga harus melindungi edit method karena bisa saja seseorang hanya mengetikkan pada get request dalam url dan tentu saja data yang diminta akan ditampilkan jika ada. Ini tentunya sangat berbahaya, Jadi langkah terakhir silahkan edit PostController.php, tepatnya pada method edit kemudian tambahkan kode berikut :

if ( ! $this->adminOrCurrentUserOwns($post)){
  throw new UnauthException;
}

Langkah diatas akan melindungi form edit dari user yang mengakses link secara langsung. Sehingga siapapun tidak dapat melihat data jika tidak di izinkan. So, sampai disini cukup mudah bukan ? Happy coding, and see you in the next chapter.

Category:
Share:

Comments