Developer Snippet Diary

Laravel Roles, Permissions using Spatie

1.

composer create-project laravel/laravel example-app

2.  setup mysql in .env file

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dbNAMEhere
DB_USERNAME=root
DB_PASSWORD=

3. install laravel breeze, or any other module that used for user authentication

4.  Install the Spatie Package with the following command:

composer require spatie/laravel-permission

5. The service provider will automatically get registered. Or you may manually add the service provider in your config/app.php file:

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

6. publish the migration

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

php artisan migrate

7. This package comes with RoleMiddleware, PermissionMiddleware and RoleOrPermissionMiddleware middleware. You can add them inside your app/Http/Kernel.php file to be able to use them through aliases.

// Note: Laravel 10+ uses $middlewareAliases = [
protected $middlewareAliases = [
    // ...
    'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
];

//if < laravel 10
protected $routeMiddleware = [
    // other middleware...
    'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
];

8. Add the necessary trait to your User model ( app/Models/User.php ) :

class User extends Authenticatable
{
    use HasRoles;

9. CREATE ROUTES

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

    Route::resource('permissions', App\Http\Controllers\PermissionController::class);
    Route::get('permissions/{permissionId}/delete', [App\Http\Controllers\PermissionController::class, 'destroy']);

    Route::resource('roles', App\Http\Controllers\RoleController::class);
    Route::get('roles/{roleId}/delete', [App\Http\Controllers\RoleController::class, 'destroy']);
    Route::get('roles/{roleId}/give-permissions', [App\Http\Controllers\RoleController::class, 'addPermissionToRole']);
    Route::put('roles/{roleId}/give-permissions', [App\Http\Controllers\RoleController::class, 'givePermissionToRole']);

    Route::resource('users', App\Http\Controllers\UserController::class);
    Route::get('users/{userId}/delete', [App\Http\Controllers\UserController::class, 'destroy']);

});

10. Download controllers and views from here and paste into your projects

https://github.com/RizwanKMW/laravel-permission

11. create the seeder with the following command:

php artisan db:seed --class="UserRolePermissionSeeder"

12. RUN THE BELOW COMMADND AND access http://abc.com/roles

php artisan serve

 

EXPLAINATION:

1. HOW TO CREATE ROLES AND PERMISSIONS

$role = \Spatie\Permission\Models\Role::create(['name' => 'manager']);
$permission = \Spatie\Permission\Models\Permission::create(['name' => 'view users']);

2. Assign permissions to created roles

$roleis = \Spatie\Permission\Models\Role::findByName("manager"); //first find role
$roleis->givePermissionTo("view users"); //then give permission by name
$role->givePermissionTo($permission); //or give created permission previously step

$roleis->syncPermissions(['view user', 'delete user']); //delete all old permissions and assign new ones

3. Remove Roles and permissions

$roleis->revokePermissionTo('delete user'); //permission remove from role
$permission->removeRole($role); //remove role from permission

4. ASSIGN ROLE TO USER

$user = \App\Models\User::find(7); 
/***Add roles,not remove existing roles. ***/
$user->assignRole('manager');
//$user->assignRole(['admin', 'editor']); 

/*** Remove all roles, and assign new one's  ***/
$user->syncRoles(['admin', 'editor']);

 

5. Setup routes to prevent user from access , only assigned role can access that routes

Route::group(['middleware' => ['role:super-admin|admin']], function() {
   //only admin or super-admin can access these routes ie 
   Route::resource('users', App\Http\Controllers\UserController::class);
});

6. Prevent methods to unauthorized permissions

if user has "create posts" permissions only He/She can access create and store methods,

public function __construct()
    {
        $this->middleware('permission:create posts', ['only' => ['create', 'store']]);
    }

7. if user has Roles Inside controllerMethods

$user = auth()->user(); // Get the authenticated user

if ($user->hasRole('admin')) {
    echo "admin";
}

//FOR MULTIPLE ROLES CHECK

if ($user->hasAnyRole(['admin','user'])) {
    echo "admin";
}

// TRY TO use to prevnet error "Call to a member function hasAnyRole() on null"
if(auth()->check() && auth()->user()->hasAnyRole(['admin'])){
    echo " secured <3";
}

8. Check permissions inside controller Method

if ($user->can('delete posts')) {
    echo "User can delete posts";
}
##### multiple permissions check
if ($user->can(['create posts', 'edit posts'])) { }

9. IN VIEWS, check if role have permission

@can('delete posts')
    <div class="xd"></div>
@endcan

10 IN VIEWS, DISPLAY CURRENT ROLES

@if (Auth::check())
    <p>Your Role: {{ Auth::user()->getRoleNames()->implode(', ') }}</p>
@endif

11. Show content if user have no permission

@if(auth()->user()->cannot('view_payment_stats'))
   <p>I have no permission view_payment_stats, so I can see this, anyone that have this permission are not allowed to see this</p>
@else
   <p>I have permission</p>
@endif

If sometime roles not work try below commands

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan permission:cache-reset


https://www.fundaofwebit.com/post/laravel-10-spatie-user-roles-and-permissions-tutorial

Posted by: R GONDAL
Email: rizikmw@gmail.com