Laravel 8 Role and Permission
Install Auth Scaffolding
composer require laravel/ui "^3.4" --dev
php artisan ui bootstrap --auth
npm install && npm run dev
Install laravel permission
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate
Untuk menggunakan spatie laravel-permission, kita bisa menambahkan trait Spatie\Permission\Traits\HasRoles ke dalam User
model. Buka app/Models/User.php
, lalu kita tambahkan statement use
di dalam class User
model.
<?php
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
// ... baris kode lainnya...
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
use HasRoles;
// ... baris kode lainnya...
}
Menambahkan Permissions
Langkah selanjutnya adalah
menambahkan beberapa permission dan juga role dengan menggunakan
database seeder sesuai dengan yang sudah kita bahas sebelumnya. Buka
kembali terminal, lalu kita run command
untuk membuat seeder.
php artisan make:seeder PermissionDemoSeeder
Setelah PermissionDemoSeeder
dibuat, selanjutnya buka file database/seeders/PermissionDemoSeeder.php
. Lalu kita ketik kode berikut ini.
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Spatie\Permission\PermissionRegistrar;
class PermissionDemoSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// reset cahced roles and permission
app()[PermissionRegistrar::class]->forgetCachedPermissions();
// create permissions
Permission::create(['name' => 'view posts']);
Permission::create(['name' => 'create posts']);
Permission::create(['name' => 'edit posts']);
Permission::create(['name' => 'delete posts']);
Permission::create(['name' => 'publish posts']);
Permission::create(['name' => 'unpublish posts']);
//create roles and assign existing permissions
$writerRole = Role::create(['name' => 'writer']);
$writerRole->givePermissionTo('view posts');
$writerRole->givePermissionTo('create posts');
$writerRole->givePermissionTo('edit posts');
$writerRole->givePermissionTo('delete posts');
$adminRole = Role::create(['name' => 'admin']);
$adminRole->givePermissionTo('view posts');
$adminRole->givePermissionTo('create posts');
$adminRole->givePermissionTo('edit posts');
$adminRole->givePermissionTo('delete posts');
$adminRole->givePermissionTo('publish posts');
$adminRole->givePermissionTo('unpublish posts');
$superadminRole = Role::create(['name' => 'super-admin']);
// gets all permissions via Gate::before rule
// create demo users
$user = User::factory()->create([
'name' => 'Example user',
'email' => 'writer@writer.com',
'password' => bcrypt('password')
]);
$user->assignRole($writerRole);
$user = User::factory()->create([
'name' => 'Example admin user',
'email' => 'admin@admin.com',
'password' => bcrypt('password')
]);
$user->assignRole($adminRole);
$user = User::factory()->create([
'name' => 'Example superadmin user',
'email' => 'superadmin@superadmin.com',
'password' => bcrypt('password')
]);
$user->assignRole($superadminRole);
}
}
Selanjutnya kita re-migrate dan juga run seeder
php artisan migrate:fresh --seed --seeder=PermissionDemoSeeder
Grant akses Super Admin
Di class PermissionDemoSeeder
, kita menambahkan role super-admin
dan di dalamnya kita belum mendefinisikan permission
untuk role tersebut. Di sini kita akan coba memberikan akses super admin melalui gate
di dalam AuthServiceProvider
. Buka file app/Providers/AuthServiceProvider.php
, lalu kita modifikasi method boot()
.
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array<class-string, class-string>
*/
protected $policies = [
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
// Implicitly grant "Super Admin" role all permission checks using can()
Gate::before(function ($user, $ability) {
if ($user->hasRole('super-admin')) {
return true;
}
});
}
}
Menggunakan permission middleware
Untuk menggunakan
middleware dari spatie laravel-permission, kita harus mendefinisikan
middleware-nya terlebih dahulu. Buka file app/Http/Kernel.php
, lalu cek sekitar baris 56 terdapat $routeMiddleware
, properties dari class Kernel
. Kita tambahkan route middleware untuk role
, permission
dan role_or_permission
dari spatie laravel-permission.
protected $routeMiddleware = [
// ...
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];
Membuat Controller dan tambahkan folder permission
AssignController
<?php
namespace App\Http\Controllers\Permission;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class AssignController extends Controller
{
public function create()
{
return view('permission.assign.create', [
'roles' => Role::get(),
'permissions' => Permission::get()
]);
}
public function store()
{
request()->validate([
'roles' => 'required',
'permissions' => 'array|required'
]);
$role = Role::find(request('role'));
$role->givePermissionTo(request('permissions'));
return back()->with('success', "Permission has been assigned to the role {$role->name}");
}
public function edit(Role $role)
{
return view('permission.assign.sync', [
'role' => $role,
'roles' => Role::get(),
'permissions' => Permission::get()
]);
}
public function update(Role $role)
{
request()->validate([
'role' => 'required',
]);
$role->syncPermissions(request('permissions'));
return redirect()->route('assign.create')->with('success', 'The permission has been synced');
}
}
Permission Controller
<?php
namespace App\Http\Controllers\Permission;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Permission;
class PermissionController extends Controller
{
public function index()
{
$permissions = Permission::get();
$permission = new Permission();
return view('permission.permission.index', compact('permissions', 'permission'));
}
public function store()
{
request()->validate([
'name' => 'required',
]);
Permission::create([
'name' => request('name'),
'guard_name' => request('guard_name') ?? 'web'
]);
return back();
}
public function edit(Permission $permission)
{
return view('permission.permission.edit', [
'permission' => $permission,
'submit' => 'Update'
]);
}
public function update(Permission $permission)
{
request()->validate([
'name' => 'required',
]);
$permission->update([
'name' => request('name'),
'guard_name' => request('guard_name') ?? 'web'
]);
return redirect()->route('permission.index');
}
public function destroy($id)
{
$permission = Permission::find($id);
$permission->delete();
return redirect()->route('permission.index')->with('pesan', 'Data berhasil di hapus');
}
}
Role Controller
<?php
namespace App\Http\Controllers\Permission;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
class RoleController extends Controller
{
public function index()
{
$roles = Role::get();
$role = new Role;
return view('permission.roles.index', compact('roles', 'role'));
}
public function store()
{
request()->validate([
'name' => 'required',
]);
Role::create([
'name' => request('name'),
'guard_name' => request('guard_name') ?? 'web'
]);
return back();
}
public function edit(Role $role)
{
return view('permission.roles.edit', [
'role' => $role,
'submit' => 'Update'
]);
}
public function update(Role $role)
{
request()->validate([
'name' => 'required',
]);
$role->update([
'name' => request('name'),
'guard_name' => request('guard_name') ?? 'web'
]);
return redirect()->route('roles.index');
}
public function destroy($id)
{
$role = Role::find($id);
$role->delete();
return redirect()->route('roles.index')->with('pesan', 'Data berhasil di hapus');
}
}
Permission : UserController
<?php
namespace App\Http\Controllers\Permission;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
class UserController extends Controller
{
public function create()
{
return view('permission.assign.user.create', [
'roles' => Role::get(),
'users' => User::has('roles')->get(),
]);
}
public function store()
{
$user = User::where('email', request('email'))->first();
$user->assignRole(request('roles'));
return back();
}
public function edit(User $user)
{
return view('permission.assign.user.edit', [
'user' => $user,
'roles' => Role::get(),
'users' => User::has('roles')->get(),
]);
}
public function update(User $user)
{
$user->syncRoles(request('roles'));
return redirect()->route('assign.user.create');
}
}
Membuat Routes
<?php
use App\Http\Controllers\Permission\AssignController;
use App\Http\Controllers\Permission\PermissionController;
use App\Http\Controllers\Permission\RoleController;
use App\Http\Controllers\Permission\UserController;
use App\Http\Controllers\UserController as UserCtrl;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Spatie\Permission\Contracts\Role;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('auth.login');
});
Auth::routes();
Route::middleware('has.role')->group(function () {
Route::view('dashboard', 'dashboard')->name('dashboard');
Route::group(['namespace' => 'Permission', 'prefix' => 'role-and-permission', 'middleware' => 'permission:assign permission'], function () {
Route::get('assignable', [AssignController::class, 'create'])->name('assign.create');
Route::post('assignable', [AssignController::class, 'store'])->name('assign.store');
Route::get('assignable/{role}/edit', [AssignController::class, 'edit'])->name('assign.edit');
Route::put('assignable/{role}/edit', [AssignController::class, 'update']);
Route::get('assign/user', [UserController::class, 'create'])->name('assign.user.create');
Route::post('assign/user', [UserController::class, 'store'])->name('assign.user.store');
Route::get('assign/{user}/user', [UserController::class, 'edit'])->name('assign.user.edit');
Route::put('assign/{user}/user', [UserController::class, 'update']);
Route::delete('assign/{user}/destroy', [UserController::class, 'destroy'])->name('assign.user.destroy');
Route::prefix('roles')->group(function () {
Route::get('', [RoleController::class, 'index'])->name('roles.index');
Route::post('create', [RoleController::class, 'store'])->name('roles.create');
Route::get('{role}/edit', [RoleController::class, 'edit'])->name('roles.edit');
Route::put('{role}/edit', [RoleController::class, 'update']);
Route::delete('{role}/destroy', [RoleController::class, 'destroy'])->name('roles.destroy');
});
Route::prefix('permission')->group(function () {
Route::get('', [PermissionController::class, 'index'])->name('permission.index');
Route::post('create', [PermissionController::class, 'store'])->name('permission.create');
Route::get('{permission}/edit', [PermissionController::class, 'edit'])->name('permission.edit');
Route::put('{permission}/edit', [PermissionController::class, 'update']);
Route::delete('{permission}/destroy', [PermissionController::class, 'destroy'])->name('permission.destroy');
});
});
Route::prefix('master-data')->group(function () {
Route::prefix('user')->middleware('permission:user create')->group(function () {
Route::get('', [UserCtrl::class, 'index'])->name('user.index');
Route::get('create', [UserCtrl::class, 'create'])->name('user.create');
Route::post('create', [UserCtrl::class, 'store'])->name('user.store');
Route::get('{user}/edit', [UserCtrl::class, 'edit'])->name('user.edit');
Route::put('{user}/edit', [UserCtrl::class, 'update'])->name('user.update');
Route::delete('{user}/edit', [UserCtrl::class, 'destroy'])->name('user.destroy');
});
});
});
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Post a Comment