andriajah Sun Mar 2021 1 year ago

Tutorial Laravel 8.x Membuat User Roles dan Permissions


User Role dan Permissions adalah bagian penting dari banyak aplikasi web. Dalam tutorial ini kita akan melihat bagaimana kita dapat mengimplementasikan peran users dan sistem permissions di laravel. Kami akan melihatnya dari awal. Kami tidak akan menggunakan paket spatie/laravel-permission  untuk melakukannya. Tapi Anda bisa menggunakan  spatie/laravel-permission untuk membuat user role dan sistem permission ini di laravel 8.   
 
Penting untuk menambahkan user role laravel dan mekanisme permission dalam aplikasi skala besar kami untuk memberikan izin kepada pengguna untuk tugas tertentu. Kita akan melihat dari awal tutorial role pengguna dan permission laravel 8. 
 
Jika Anda tidak tahu cara membuat role dan permission laravel 8, maka Anda adalah tempat yang tepat. Saya akan mengajari Anda dari awal role dan permission laravel. Tetapi dalam tutorial ini kita akan melakukan role pengguna dan permission di laravel menggunakan kode khusus kita sendiri. Jadi mari kita mulai bagaimana menerapkan & mengatur peran dan izin di Laravel.
 
Saya memperbarui tutorial ini untuk versi laravel 8. Jadi jika Anda menghadapi kesalahan apa pun, maka Anda dapat memeriksa repositori git. Mari kita mulai tutorial urser role dan permission laravel 8.
 

Langkah 1: Unduh Proyek Laravel

Buka terminal Anda dan buat proyek Laravel baru dengan mengetikkan perintah berikut
composer create-project --prefer-dist laravel/laravel blog

Langkah 2: Buat Auth

Jika Anda menggunakan laravel versi 6, jalankan perintah di bawah ini untuk membuat auth
composer require laravel/ui --dev
php artisan ui vue --auth
npm install
npm run watch
Jika Anda menggunakan laravel versi 6 di bawah ini, jalankan perintah di bawah ini untuk membuat auth
php artisan make:auth

Langkah 3: Buat Model

Kami membutuhkan model untuk membuat user role dan permission. Jadi mari buat model kita menggunakan perintah di bawah ini.
php artisan make:model Permission -m
php artisan make:model Role -m
Seperti yang Anda ketahui, -m flag akan membuat file migrasi untuk model tersebut. Sekarang Anda akan memiliki dua file migrasi baru yang menunggu Anda untuk menambahkan bidang baru.

Langkah 4: Edit file migrasi

public function up()
    {
       Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email',191)->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
    });
}
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePermissionsTable extends Migration
{
    
    public function up()
    {
        Schema::create('permissions', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name'); // edit posts
            $table->string('slug'); //edit-posts
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('permissions');
    }
}
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateRolesTable extends Migration
{
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name'); // edit posts
            $table->string('slug'); //edit-posts
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('roles');
    }
}

Langkah 5: Menambahkan tabel pivot

Untuk tabel pivot pertama ini, kami akan membuat file migrasi baru untuk tabel users_permissions. Jadi jalankan perintah di bawah ini untuk membuat
php artisan make:migration create_users_permissions_table --create=users_permissions
Untuk tabel pivot antara user dan permission ini, skema kita akan terlihat seperti ini

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

class CreateUsersPermissionsTable extends Migration
{
    public function up()
    {
        Schema::create('users_permissions', function (Blueprint $table) {
            $table->unsignedInteger('user_id');
            $table->unsignedInteger('permission_id');

            //FOREIGN KEY CONSTRAINTS
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
 
            //SETTING THE PRIMARY KEYS
            $table->primary(['user_id','permission_id']);
        });
    }

    public function down()
    {
        Schema::dropIfExists('users_permissions');
    }
}
Sekarang mari kita buat tabel pivot untuk users_roles .
php artisan make:migration create_users_roles_table --create=users_roles
Bidang di dalam tabel ini akan sama seperti di tabel users_permissions. Skema kami untuk tabel ini akan terlihat seperti:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersRolesTable extends Migration
{
    public function up()
    {
        Schema::create('users_roles', function (Blueprint $table) {
            $table->unsignedInteger('user_id');
            $table->unsignedInteger('role_id');

         //FOREIGN KEY CONSTRAINTS
           $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
           $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');

         //SETTING THE PRIMARY KEYS
           $table->primary(['user_id','role_id']);
        });
    }

    public function down()
    {
        Schema::dropIfExists('users_roles');
    }
}
Di bawah Peran tertentu, Pengguna mungkin memiliki Izin khusus
 
Misalnya, pengguna mungkin memiliki izin untuk memposting topik, dan admin mungkin memiliki izin untuk mengedit atau menghapus topik. Dalam kasus ini, mari kita siapkan tabel baru untuk role_permissions untuk menangani kompleksitas ini.
php artisan make:migration create_roles_permissions_table --create=roles_permissions
Skema akan seperti:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateRolesPermissionsTable extends Migration
{
    public function up()
    {
        Schema::create('roles_permissions', function (Blueprint $table) {
             $table->unsignedInteger('role_id');
             $table->unsignedInteger('permission_id');

             //FOREIGN KEY CONSTRAINTS
             $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
             $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');

             //SETTING THE PRIMARY KEYS
             $table->primary(['role_id','permission_id']);
        });
    }

    public function down()
    {
        Schema::dropIfExists('roles_permissions');
    }
}
Sekarang jalankan perintah berikut untuk membuat migrasi
php artisan migrate

Langkah 6: Setting Relationships

Kita akan mulai dengan membuat hubungan antara peran dan tabel izin. Di Role.php kami, Permision.php.
 
App/Role.php
public function permissions() {

   return $this->belongsToMany(Permission::class,'roles_permissions');
       
}

public function users() {

   return $this->belongsToMany(User::class,'users_roles');
       
}
App/Permission.php
public function roles() {

   return $this->belongsToMany(Role::class,'roles_permissions');
       
}

public function users() {

   return $this->belongsToMany(User::class,'users_permissions');
       
}

Langkah 7: Membuat Trait

Di dalam direktori aplikasi kita, mari buat direktori baru dan beri nama permission dan buat file baru bernama  HasPermissionsTrait.php. Ciri kecil yang bagus telah disiapkan untuk menangani user relation. Kembali ke model User kami, cukup import trait ini dan kami siap melakukannya.
 
app/User.php
namespace App;

use App\Permissions\HasPermissionsTrait;

class User extends Authenticatable
{
    use HasPermissionsTrait; //Import The Trait
}
Sekarang buka  HasPermissionsTrait.php dan tempel kode berikut ini.
App/Permissions/HasPermissionsTrait.php
namespace App\Permissions;

use App\Permission;
use App\Role;

trait HasPermissionsTrait {

   public function givePermissionsTo(... $permissions) {

    $permissions = $this->getAllPermissions($permissions);
    dd($permissions);
    if($permissions === null) {
      return $this;
    }
    $this->permissions()->saveMany($permissions);
    return $this;
  }

  public function withdrawPermissionsTo( ... $permissions ) {

    $permissions = $this->getAllPermissions($permissions);
    $this->permissions()->detach($permissions);
    return $this;

  }

  public function refreshPermissions( ... $permissions ) {

    $this->permissions()->detach();
    return $this->givePermissionsTo($permissions);
  }

  public function hasPermissionTo($permission) {

    return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission);
  }

  public function hasPermissionThroughRole($permission) {

    foreach ($permission->roles as $role){
      if($this->roles->contains($role)) {
        return true;
      }
    }
    return false;
  }

  public function hasRole( ... $roles ) {

    foreach ($roles as $role) {
      if ($this->roles->contains('slug', $role)) {
        return true;
      }
    }
    return false;
  }

  public function roles() {

    return $this->belongsToMany(Role::class,'users_roles');

  }
  public function permissions() {

    return $this->belongsToMany(Permission::class,'users_permissions');

  }
  protected function hasPermission($permission) {

    return (bool) $this->permissions->where('slug', $permission->slug)->count();
  }

  protected function getAllPermissions(array $permissions) {

    return Permission::whereIn('slug',$permissions)->get();
    
  }

}

Di sini, kami mengulangi role dan memeriksa bidang slug, jika peran spesifik itu ada. Anda dapat memeriksa atau men-debug ini dengan menggunakan:

$user = $request->user(); //getting the current logged in user
dd($user->hasRole('admin','editor')); // and so on

Langkah 8: Buat CustomProvider

Kami akan menggunakan petunjuk "can" dari Laravel untuk memeriksa apakah Pengguna memiliki Izin. dan alih-alih menggunakan  $user->hasPermissionTo().
 
kita akan menggunakan  $user->can()  Untuk melakukannya, kita perlu membuat PermissionsServiceProvider baru untuk otorisasi
 
php artisan make:provider PermissionsServiceProvider

Daftarkan service provider Anda dan lanjutkan ke metode boot untuk memberi kami Gateway untuk menggunakan metode can().

namespace App\Providers;

use App\Permission;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;

class PermissionsServiceProvider extends ServiceProvider
{
   
    public function register()
    {
        //
    }

    public function boot()
    {
        try {
            Permission::get()->map(function ($permission) {
                Gate::define($permission->slug, function ($user) use ($permission) {
                    return $user->hasPermissionTo($permission);
                });
            });
        } catch (\Exception $e) {
            report($e);
            return false;
        }

        //Blade directives
        Blade::directive('role', function ($role) {
             return "if(auth()->check() && auth()->user()->hasRole({$role})) :"; //return this if statement inside php tag
        });

        Blade::directive('endrole', function ($role) {
             return "endif;"; //return this endif statement inside php tag
        });

    }
}

sekarang kita harus mendaftarkan PermissionsServiceProvider kita. Buka file berikut ini, tambahkan ini di array providers.
config\app.php

 'providers' => [

        App\Providers\PermissionsServiceProvider::class,
    
 ],

Anda dapat mempelajari lebih lanjut tentang  Gate facade Laravel di dokumentasi Laravel . Anda dapat mengujinya sebagai:

dd($user->can('permission-slug'));

Langkah 9: Tambahkan Data Dummy Untuk Diperiksa

Untuk membuat tutorial role dan permission, kami membutuhkan data dummy untuk memeriksa akses user kami. Untuk membuatnya, tempel kode berikut ini ke slug dibawah ini.
Route::get('/roles', 'PermissionController@Permission');
App\Http\Controllers\PermissionController.php
namespace App\Http\Controllers;

use App\Permission;
use App\Role;
use App\User;
use Illuminate\Http\Request;

class PermissionController extends Controller
{   

    public function Permission()
    {   
    	$dev_permission = Permission::where('slug','create-tasks')->first();
		$manager_permission = Permission::where('slug', 'edit-users')->first();

		//RoleTableSeeder.php
		$dev_role = new Role();
		$dev_role->slug = 'developer';
		$dev_role->name = 'Front-end Developer';
		$dev_role->save();
		$dev_role->permissions()->attach($dev_permission);

		$manager_role = new Role();
		$manager_role->slug = 'manager';
		$manager_role->name = 'Assistant Manager';
		$manager_role->save();
		$manager_role->permissions()->attach($manager_permission);

		$dev_role = Role::where('slug','developer')->first();
		$manager_role = Role::where('slug', 'manager')->first();

		$createTasks = new Permission();
		$createTasks->slug = 'create-tasks';
		$createTasks->name = 'Create Tasks';
		$createTasks->save();
		$createTasks->roles()->attach($dev_role);

		$editUsers = new Permission();
		$editUsers->slug = 'edit-users';
		$editUsers->name = 'Edit Users';
		$editUsers->save();
		$editUsers->roles()->attach($manager_role);

		$dev_role = Role::where('slug','developer')->first();
		$manager_role = Role::where('slug', 'manager')->first();
		$dev_perm = Permission::where('slug','create-tasks')->first();
		$manager_perm = Permission::where('slug','edit-users')->first();

		$developer = new User();
		$developer->name = 'Mahedi Hasan';
		$developer->email = '[email protected]';
		$developer->password = bcrypt('secrettt');
		$developer->save();
		$developer->roles()->attach($dev_role);
		$developer->permissions()->attach($dev_perm);

		$manager = new User();
		$manager->name = 'Hafizul Islam';
		$manager->email = '[email protected]';
		$manager->password = bcrypt('secrettt');
		$manager->save();
		$manager->roles()->attach($manager_role);
		$manager->permissions()->attach($manager_perm);

		
		return redirect()->back();
    }
}

Sekarang buka url ini dan tekan enter pada keyboard Anda. Kemudian Anda akan melihat beberapa data dummy untuk tabel-tabel berikut. Untuk mengujinya di file route Anda, kita bisa die dan dump:
$user = $request->user();
dd($user->hasRole('developer')); //will return true, if user has role
dd($user->givePermissionsTo('create-tasks'));// will return permission, if not null
dd($user->can('create-tasks')); // will return true, if user has permission
Di dalam file view kami, kami dapat menggunakannya seperti:
@role('developer')

 Hello developer

@endrole
Ini berarti hanya pengguna yang dapat melihatnya yang berperan sebagai developer. Sekarang Anda dapat menggunakan banyak peran yang Anda inginkan.

Langkah 10: Siapkan Middleware

Untuk melindungi route kita, kita dapat mengatur middleware untuk melakukannya.
php artisan make:middleware RoleMiddleware
Tambahkan middleware ke dalam kernel Anda & siapkan metode pegangan sebagai berikut
 
Aplikasi\Http\Middleware\RoleMiddleware.php
namespace App\Http\Middleware;

use Closure;

class RoleMiddleware
{

    public function handle($request, Closure $next, $role, $permission = null)
    {
        if(!$request->user()->hasRole($role)) {

             abort(404);

        }

        if($permission !== null && !$request->user()->can($permission)) {

              abort(404);
        }

        return $next($request);

    }
}
Sekarang kita harus mendaftarkan RoleMiddleware ini . Jadi tambahkan kode berikut ini untuk mendaftarkannya.
 
Aplikasi\Http\Kernel.php
protected $routeMiddleware = [
    .
    .
    'role' => \App\Http\Middleware\RoleMiddleware::class,
];

Saat ini di route kami, kami dapat melakukan sesuatu seperti ini

Route::group(['middleware' => 'role:developer'], function() {

   Route::get('/admin', function() {

      return 'Welcome Admin';
      
   });

});

Sekarang Anda dapat menggunakan controller Anda seperti di bawah ini untuk memberikan izin dan akses pengguna.

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


public function store(Request $request)
{
    if ($request->user()->can('create-tasks')) {
        //Code goes here
    }
}

public function destroy(Request $request, $id)
{   
    if ($request->user()->can('delete-tasks')) {
      //Code goes here
    }

}

Sekarang hanya pengguna tersebut yang dapat mengakses route ini yang berperan sebagai developer. Harap Anda memahami prosedur total. Semoga bisa membantu Anda.

create permissions laravel create user role laravel laravel 8 laravel