4 Min Read

Menggunakan Laravel Permission dari Spatie

iman-sugirman Iman Sugirman

Pada setiap aplikasi biasanya ada beberapa batasan untuk beberapa orang. Hal ini bisa dibatasi berdasarkan roles atau jabatan seseorang dalam sebuah perusahaan, atau jika jabatan tersebut ada lebih dari 1 orang dan masing-masingnya ada beberapa perbedaan maka ada juga fungsi permission dalam sebuah aplikasi, yang berfungsi untuk memilah dan memilih beberapa akses yang bisa disesuaikan dengan jabatan atau orang didalamnya.

Solusi untuk melakukan pembatasan roles dan permission itu menggunakan package dari Spatie yang memang sudah banyak dipakai oleh para developer laravel.

Instalasi Laravel Permission dari Spatie Package

Untuk menginstal anda bisa menulis perintah :

composer require spatie/laravel-permission

Opsional: Package akan didaftarkan secara otomatis. Atau Anda dapat menambahkan di app.php secara manual di file config/app.php Anda:

'providers' => [
    // ...
    Spatie\Permission\PermissionServiceProvider::class,
];

Setelah instalasi maka anda bisa mempublish file config dengan cara :

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

Dan file permission.php akan ada di folder config anda untuk anda bisa mengkonfigurasikan pengaturan permission. Jangan lupa setelah anda mempublish anda sebaiknya mengoptimasikan dan clear cache untuk aplikasi anda.

php artisan optimize:clear
 # or
php artisan config:clear

Jalankan perintah migration dari console laravel anda.

php artisan migrate

Integrasikan Dengan Model User anda

Integrasikan permission dengan User model anda yang berada di App\Models :

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // ...
}

Untuk membuat salah satu Role anda bisa menggunakan eloquent dengan cara seperti ini :

use Spatie\Permission\Models\Role;

$role = Role::create(['name' => 'writer']);

Maka hasilnya anda akan melihat di database tabel roles akan tampil writer. Selanjutnya anda bisa membuat permission dengan eloquent seperti ini :

use Spatie\Permission\Models\Permission;

$permission = Permission::create(['name' => 'edit_articles']);

Lalu penggabungan dalam setiap role itu jika memiliki permission maka akan seperti ini :

$role->givePermissionTo($permission);

yang mana artinya adalah $role yang bernama writer memiliki izin untuk edit_articles jika anda ingin mengedit roles tersebut maka nanti anda harus menggunakan eloquent di method update seperti ini :

$role->syncPermissions($permissions);

Menetapkan User Mempunyai Salah Satu Roles

Selanjutnya anda akan menetapkan salah satu User anda akan menggunakan kode seperti ini :

// User dengan id 1
$user = User::find(1);

// User ditetapkan sebagai `writer` dan sudah terotomatis user ini mendapatkan izin permission yang berkaitan dengan roles writer
$user->assignRole('writer');

// Atau anda bisa juga menetapkan 2 roles sekaligus
$user->assignRole('writer', 'admin');

// Dan ketika anda melakukan update bisa juga menggunakan 
$user->syncRoles(['writer', 'admin']);

Dan anda juga bisa mencari user dengan roles tertentu menggunakan Eloquent :

// User mana saja yang memiliki roles writer
$user->hasRole('writer');

Setelah anda men-setup dan menentukan user tersebut ditetapkan roles sebagai writer contohnya. Ini tidak bisa langsung anda gunakan pembatasannya di route laravel. Untuk lebih lengkap di laravel ada yang berfungsi sebagai middleware dan package ini bisa anda gunakan sebagai middleware dengan cara menggunakan method can bawaan dari Laravel Gate dan roles tertentu.

Dan nanti akan bisa digunakan seperti ini di file route anda :

Route::group(['middleware' => ['can:edit_articles']], function () {
    //
});

Maka dari itu anda harus memasukan middleware bawaan dari Spatie Package dengan cara mengedit file app/Http/Kernel.php seperti ini :

protected $routeMiddleware = [
    // ...
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];

Anda bisa menggunakan Pembatasan route dengan cara seperti ini :

Route::group(['middleware' => ['role:super-admin']], function () {
    //
});

Route::group(['middleware' => ['permission:publish articles']], function () {
    //
});

Route::group(['middleware' => ['role:super-admin','permission:publish articles']], function () {
    //
});

Route::group(['middleware' => ['role_or_permission:super-admin|edit articles']], function () {
    //
});

Route::group(['middleware' => ['role_or_permission:publish articles']], function () {
    //
});

Atau bisa juga menggunakan multi dengan cara menambahkan pipa | seperti ini :

Route::group(['middleware' => ['role:super-admin|writer']], function () {
    //
});

Route::group(['middleware' => ['permission:publish articles|edit articles']], function () {
    //
});

Route::group(['middleware' => ['role_or_permission:super-admin|edit articles']], function () {
    //
});

Tidak hanya itu anda juga masih bisa membatasi di Controller dalam method __construct seperti ini :

public function __construct()
{
    $this->middleware(['role:super-admin','permission:publish articles|edit articles']);
}

atau bisa seperti ini juga :

public function __construct()
{
    $this->middleware(['role_or_permission:super-admin|edit articles']);
}

Jika anda ingin menggunakan Custom Exception dengan cara menambahkan di file app/Exceptions/Handler.php dengan cara seperti ini :

public function render($request, Throwable $exception)
{
    if ($exception instanceof \Spatie\Permission\Exceptions\UnauthorizedException) {
        return response()->json([
            'responseMessage' => 'You do not have the required authorization.',
            'responseStatus'  => 403,
        ]);
    }

    return parent::render($request, $exception);
}

Membatasi View Dengan Blade Directive

Jika sebelumnya anda bisa membatasi route di laravel dengan middleware anda bisa juga membatasi tampilan dengan menggunakan teknik blade directive contohnya saja ketika roles manager bisa melihat tampilan a dan tidak bisa melihat tampilan b namun seorang writer / roles lain tidak bisa melihat tampilan a namun bisa melihat tampilan b anda bisa menggunakan metode seperti ini :

@role('manager')
    a
@else
    b
@endrole

// Atau bisa juga spesifik

@role('manager')
    a
@else
    b
@endrole

// Bisa juga menggunakan @hasrole

@hasrole('manager')
    I am a manager!
@else
    I am not a manager...
@endhasrole

Jika ingin menggunakan method can anda bisa menggunakan seperti ini :

@can('edit_articles')
  //
@endcan

atau

@if(auth()->user()->can('edit articles') && $some_other_condition)
  //
@endif

Untuk Lebih jelasnya anda bisa melihat dokumentasi Spatie Permission

Demikian tutorial tentang Menggunakan Laravel Permission dari Spatie