Disini kita akan coba membangun sistem role dan authorization pada framework Laravel. Untuk urusan authorization ini Laravel sudah menyediakan fitur yang disebut dengan Gate, jadi setiap user akan melakukan suatu aksi maka harus melewati Gate ini terlebih dahulu dan ketika user memenuhi syarat maka user akan ijinkan melakukan akses tersebut dan apabila tidak maka akan langsung redirect dengan status 403 yaitu forbidden.

Role dan Authorization adalah suatu fitur dimana kita bisa memberikan ijin kepada user berdasarkan role dan permission dari user itu sendiri. Sistem ini sangat penting dan sangat krusial sebab ini berhubungan dengan security.

Bayangkan saja ketika kalian login sebagai kayawan biasa disuatu sistem perusahaan kemudian kalian bisa dengan bebas mengakses laporan transaksi yang harusnya hanya bisa dilihat oleh. Nah maka dari itu perlu adanya proses authorization dari setiap aksi yang dilakukan oleh user.

Ok kedengarannya memang agak rumit tapi saya akan menjelaskan langkah - langkah-nya agar mudah kalian implementasikan.

 

Buat Migration

Ok langsung saja kelangkah yang pertama yaitu membuat file migration yang dibutuhkan. Nah disini saya membuat skenario 1 role dimiliki oleh banyak user dan 1 role bisa memiliki lebih dari 1 permission begitu juga sebaliknya.

Dari skenario diatas berarti migration yang kita butuhkan adalah roles, permissions dan permission_role.

Mungkin kalian bertanya kenapa ada tabel permission_role, jawabannya adalah karena tabel roles dan permissions akan berelasi banyak ke banyak dari perlu adanya tabel bantu untuk menghubungkan kedua tabel tersebut.

Ok langsung saja kita buat ketiga migration tersebut.

php artisan make:migration create_roles_table && php artisan make:migration create_permissions_table && php artisan make:migration create_permission_role_table

Kemudian kita tambahkan field name pada create_roles_table.

$table->string("name", 20);

Hal yang sama juga kita lakukan pada create_permissions_table.

$table->string('name', 30);

Kemudian yang terakhir create_permission_role_table.

$table->bigInteger('role_id')->unsigned();
$table->bigInteger('permission_id')->unsigned();

Dan yang terakhir kita tambahkan field role_id pada create_users_table.

$table->bigInteger('role_id')->unsigned()->default(0);

Ok ketika semua sudah siap kalian tinggal jalankan migratenya.

php artisan migrate

Note: jika terdapat error Specified key was to long maka kalian perlu set panjang default string pada AppServiceProvider.php dengan kode berikut.

Illuminate\Support\Facades\Schema::defaultStringLength(191);

Letakan kode diatas pada method register, dan setelah itu hapus semua tabel yang ada pada database kalian kemudian lakukan migrate sekali lagi.

 

Model dan Seeder

Ok setelah pembuatan migration selesai dan proses migrate berjalan lancar langkah selanjutnya adalah membuat Model beserta Seeder. Seeder kita perlukan untuk membuat sample data nantinya.

Model

Langsung saja keproses pembuatan model. Ada 2 model yang akan kita buat yaitu Role dan Permission.

php artisan make:model Role && php artisan make:model Permission

Karena sebelumnya kita menambahkan role_id pada create_users_table, maka kita juga lakukan hal yang sama pada model User dengan menambahkannya pada attribute $fillabel.

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

Kemudian isi dari model Role kurang lebih seperti ini.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    protected $fillable = [
        'name'
    ];

    public function permissions()
    {
        return $this->belongsToMany(Permission::class);
    }
}

Bisa kita lihat bersama model Role ini akan berelasi many to many dengan Permission. Tapi jika kalian masih bingung tentang Relationship kalian bisa membaca artikel saya yang membahan tentang Dasar Relationship di Laravel.

Ok selanjutnya isi dari model Permission seperti ini.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Permission extends Model
{
    protected $fillable = [
        'name'
    ];
}

Dan yang terakhir kita tambahkan 2 method berikut pada model User.

public function role() {
    return $this->belongsTo(Role::class);
}

public function hasPermission($permission) {
    return $this->role->permissions()->where('name', $permission)->first() ?: false;
}

Karena user berelasi dengan role maka kita perlu method role() untuk mengakses role dari user, dan method hasPermission untuk mengecek apakah user memiliki permission tertentu method ini jga akan digunakan pada saat pembuatan Gate.

Seeder

Setelah pembuatan model selesai maka kita akan mengisi tabel dari masing - masing tabel roles, permissions, dan users dengan seeder.

Pertama kita buat terlebih dahulu seeder untuk masing - masing tabel.

php artisan make:seeder RolesTableSeeder && php artisan make:seeder PermissionsTableSeeder && php artisan make:seeder UsersTableSeeder

File seeder yang kalian buat bisa kalian temukan pada folder database > seeds, Kemudian pada RolesTableSeeder.php kita akan isi dengan role admin, staff dan ceo.

Kita isi method run pada RolesTableSeeder.php.

App\Role::create([
      'name' => 'admin'
]);

App\Role::create([
      'name' => 'staff'
]);

App\Role::create([
      'name' => 'ceo'
]);

Bisa dilihat dari kode diatas kita mengisi data roles dengan Model role yang kita buat sebelumnya. Hal yang sama juga kita lakukan pada PermissionsTableSeeder.php hanya saja agak sedikit berbeda karena kita akan meng-assign masing - masing role yang kita buat.

App\Permission::create([
       'name' => 'view data' // id 1
]);
App\Permission::create([
       'name' => 'create data' // id 2
]);
App\Permission::create([
       'name' => 'edit data' // id 3
]);
App\Permission::create([
       'name' => 'update data' // id 4
]);
App\Permission::create([
       'name' => 'delete data' // id 5
]);

$admin = App\Role::where('name', 'admin')->first();
$admin->permissions()->attach([1, 2, 5]);

$staff = App\Role::where('name', 'staff')->first();
$staff->permissions()->attach([1, 2, 3, 4]);

$ceo = App\Role::where('name', 'ceo')->first();
$ceo->permissions()->attach([1, 2, 3, 4, 5]);

Seperti yang saya bilang sebelumnya kita tidak hanya mengisi data permission tapi juga sekaligus memberikan permission ke masing - masing role, karena pada model Role kita menggunakan relasi belongsToMany untuk mengakses model Permission maka kita bisa menggunakan method attach untuk mengisi role_id dan permission_id pada tabel role_permission.

Lalu pada UsersTableSeeder.php kita membuat 3 user dengan role yang berbeda - beda.

App\User::create([
       'name' => 'Mr. Junk',
       'email' => 'junk@gmail.com',
       'password' => bcrypt('secret'),
       'role_id' => 1
]);

App\User::create([
       'name' => 'Mr. Jenkin',
       'email' => 'jenkin@gmail.com',
       'password' => bcrypt('secret'),
       'role_id' => 2
]);

App\User::create([
       'name' => 'Miss. Puff',
       'email' => 'puff@gmail.com',
       'password' => bcrypt('secret'),
       'role_id' => 3
]);     

Jika sudah maka kita akan memanggil semua seeder yang sudah kita buat pada file DatabaseSeeder.php

$this->call(RolesTableSeeder::class);
$this->call(PermissionsTableSeeder::class);
$this->call(UsersTableSeeder::class);

Dan terakhir kita jalankan seedernya.

php artisan db:seed

 

Membuat Gate

Ok sampai disini kita sudah membuat roles dan permissions, dan sekarang tinggal proses authorization-nya saja. Seperti yang saya bilang diawal kita akan menggunakan Gate dari Laravel.

Gate bisa didefinisikan pada app > Providers > AuthServiceProvider.php. Nah pada method boot kita tambahkan dengan kode berikut.

Gate::before(function($user, $ability) {
      if ($user->hasPermission($ability)) {
            return true;
      }
});

Maksud dari kode diatas adalah kita mengecek user yang saat ini sedang login apakah memenuhi kriteria untuk melakukan sebuah aksi dimana pada hal ini kita mengecek dari permissionnya melalui method hasPermission yang sudah kita buat sebelumnya.

 

Eksekusi

Ok sekarang waktunya untuk testing. Untuk testing kita perlu sistem autentikasi terlebih dahulu agar menghemat waktu langsung saja generate auth dengan artisan.

php artisan make:auth

Kemudian kita buat controller baru dengan nama AuthorizationController.

php artisan make:controller AuthorizationController

Kemudian isi AuthorizationController dengan method - method ini.

    public function __construct()
    {
        $this->middleware('auth');
    }

    public function viewData()
    {
        $this->authorize('view data');

        return 'view data';
    }

    public function createData()
    {
        $this->authorize('create data');

        return 'create data';
    }

    public function editData()
    {
        $this->authorize('edit data');

        return 'edit data';
    }

    public function updateData()
    {
        $this->authorize('update data');

        return 'update data';
    }

    public function deleteData()
    {
        $this->authorize('delete data');

        return 'delete data';
    }

Bisa kita lihat dari kode diatas disetiap method kita harus meng-authorize user terlebih dahulu sebelum menuju proses selanjutnya. Sebenarnya ada banyak cara untuk autorisasi bisa dari middleware, view dan controller tapi pada tutorial ini saya contohkan yang dari controller.

Kemudian kita setup route-nya.

Route::get('view-data', 'AuthorizationController@viewData');
Route::get('create-data', 'AuthorizationController@createData');
Route::get('edit-data', 'AuthorizationController@editData');
Route::get('update-data', 'AuthorizationController@updateData');
Route::get('delete-data', 'AuthorizationController@deleteData');

Ok sekarang kita menuju browser ke halaman login kita login dengan email: junk@gmail.com password: secret.

Karena kita login sebagai user sekarang memiliki role admin maka kita hanya akan bisa mengakses page view-data, create-data, dan delete-data saja sesuai dengan permission yang dimiliki oleh user.

dan jika kita mengkases page katanlah edit-data maka kita akan diarahkan pada page Forbidden karena kita tidak memenuhi kreteria untuk mengakses page tersebut.

Kalian juga bisa tes dengan 2 user yang lainnya agar bisa lebih memahami lagi.

 

Ok dengan ini berakhir sudah tutorial kali ini semoga bermanfaat dan jika ada kendalah ataupun ingin diskusi langsung saja dikolom komentar ya :)
Untuk kalian yg lagi cari monitor atau aksesoris seperti keyboard, mousepad dan mouse bisa lihat rekomendasi saya di tokopedia ya.